<template>
  <div class="image-editor" @click="handleEditorClick">
    <!-- 主画布区域 -->
    <div class="canvas-container" ref="canvasContainer" :style="{
      width: canvasWidth + 'px',
      height: (canvasHeight) + 'px',
      ...canvasContainerStyle
    }">
      <canvas ref="mainCanvas" class="main-canvas" @click="handleCanvasClick" @mousedown="handleMouseDown"
        @mousemove="handleMouseMove" @mouseup="handleMouseUp" @mouseleave="handleMouseLeave"></canvas>
      
      <!-- 画笔绘制层 -->
      <canvas ref="brushCanvas" class="brush-canvas" style="opacity: 0.5;"></canvas>
      
      <!-- 选区边框显示层 -->
      <canvas ref="selectionCanvas" class="selection-canvas"></canvas>
      
      <!-- 蚂蚁线显示层 -->
      <canvas ref="antsCanvas" class="ants-canvas"></canvas>

      <!-- 图片缩放控制点显示层 -->
      <canvas ref="controlCanvas" class="control-canvas"></canvas>
      
      <!-- 自动选区显示层 -->
      <canvas ref="autoSelectCanvas" class="auto-select-canvas"></canvas>
      
      <!-- 扫光loading效果 -->
      <div v-if="isScanning" class="scanning-overlay" :style="scanningOverlayStyle">
        <div class="scanning-background"></div>
        <div class="scanning-light"></div>
      </div>
    </div>
    <div class="mode-wrapper" v-if="currentMode !== 'remove'" :style="{
      height: `calc(100vh - (${canvasHeight} + 'px'))`,
      ...modeWrapperStyle
    }">
      <div class="mode-header">
        <div :class="['mode-header-title', editType === 'STORYBOARD' ? 'selected' : '']"
          @click="editType = 'STORYBOARD'">图像编辑</div>
        <!-- <div :class="['mode-header-title', editType === 'MULTI_BODY' ? 'selected' : '']"
          @click="editType = 'MULTI_BODY';closeSecondLevel()">多主体</div> -->
        <div class="flex gap-12px">
          <el-select v-model="modelProvider" :suffix-icon="CaretBottom" placeholder="选择模型"
            style="width: 180px" size="small">
            <el-option label="即梦4" value="JIMENG_4" />
            <el-option label="图片V2" value="SEED" />
            <el-option label="nano banana" value="GEMINI" />
          </el-select>
          <el-select v-model="resultNum" :suffix-icon="CaretBottom" placeholder="生成张数"
            style="width: 70px" size="small">
            <el-option label="1张" :value="1" />
            <el-option label="2张" :value="2" v-if="modelProvider !== 'GEMINI'"/>
            <el-option label="3张" :value="3" v-if="modelProvider !== 'GEMINI'"/>
            <el-option label="4张" :value="4" v-if="modelProvider !== 'GEMINI'"/>
          </el-select>
        </div>
      </div>
      <div class="mode-content" v-if="editType === 'STORYBOARD'">
        <div class="reference-image-container" @mouseenter="showReferenceDeleteIcon = true" @mouseleave="showReferenceDeleteIcon = false">
          <PicUpload 
            ref="storyboardReferenceUpload" 
            :editable="true"
            :business-id="props.businessId"
            :business-type="props.businessType"
            :roles="props.roles"
            :drama-id="props.dramaId"
            @finish="handleCoverUpload" 
            @edit="handleReferenceImageEdit"
            uploadText="参考图" 
            placeholderWidth="86" 
            placeholderHeight="120" 
          />
          <div v-if="imageFileKey && showReferenceDeleteIcon" class="delete-icon" @click="removeReferenceImage">
            <svg-icon icon-class="guanbi" color="#64687A" :size="10" />
          </div>
        </div>
        <textarea v-model="prompt"
          style="color:#1C1D29;font-size:14px;padding:8px 12px;flex:1;height: 120px;resize: none;"
          class="w-full border border-gray-200 rounded-lg focus:outline-none focus:ring-1 focus:ring-blue-500 transition-all"
          placeholder="请输入提示词，描述想创作的画面内容"></textarea>
        <div :class="['send-btn', prompt.trim() === '' ? 'disabled' : '']" @click="generateMask">
          <svg-icon class="opt-icon" color="#fff" icon-class="fasong" />
        </div>

      </div>
      <div class="mode-content" v-if="editType === 'MULTI_BODY'">
        <!-- 堆叠图片展示 -->
        <div v-if="selectedActors.length > 0" class="stacked-images-container" @mouseenter="showExpandedImages = true"
          @mouseleave="showExpandedImages = false">
          <!-- 堆叠状态 -->
          <div v-show="!showExpandedImages" class="stacked-images">
            <div v-for="(actor, index) in selectedActors" :key="actor.actorId + '-' + index" class="stacked-image"
              :style="{
                transform: `rotate(${getStackedImageRotation(index)}deg)`,
                zIndex: index + 1
              }">
              <img :src="actor.imageUrl" :alt="actor.actorName" />
            </div>
          </div>

          <!-- 展开状态 -->
          <div v-show="showExpandedImages" class="expanded-images">
            <div v-for="(actor, index) in selectedActors" :key="actor.actorId + '-expanded-' + index"
              class="expanded-image" @mouseenter="showDeleteIcon[index] = true"
              @mouseleave="showDeleteIcon[index] = false">
              <img :src="actor.imageUrl" :alt="actor.actorName" />
              <div v-if="showDeleteIcon[index]" class="delete-icon" @click="removeSelectedActor(index)">
                <svg-icon icon-class="guanbi" color="#64687A" :size="10" />
              </div>
            </div>
          </div>
        </div>

        <div class="reference-image-container tooltip-wrapper" @mouseenter="showReferenceDeleteIcon = true" @mouseleave="showReferenceDeleteIcon = false">
          <PicUpload 
            ref="multiBodyReferenceUpload" 
            :editable="true"
            :business-id="props.businessId"
            :business-type="props.businessType"
            :roles="props.roles"
            :drama-id="props.dramaId"
            @finish="handleCoverUpload" 
            @edit="handleReferenceImageEdit"
            uploadText="参考图" 
            placeholderWidth="86" 
            placeholderHeight="120" 
          />
          <div v-if="subjectFileKey && showReferenceDeleteIcon" class="delete-icon" @click="removeReferenceImage">
            <svg-icon icon-class="guanbi" color="#64687A" :size="10" />
          </div>
          <div v-if="subjectFileKey" class="hover-tooltip">参考图</div>
        </div>

        <div class="select-wrapper tooltip-wrapper" @mouseenter="sceneImageHovered = true" @mouseleave="sceneImageHovered = false">
          <!-- 场景图片显示区域 -->
          <div v-if="sceneImageUrl" class="scene-image-container">
            <img :src="sceneImageUrl" alt="场景图" class="scene-image" />
            <!-- hover时显示的按钮覆盖层 -->
            <div v-if="sceneImageHovered" class="scene-image-overlay">
              <div class="select-btn" @click="handleSceneImageUpload" :disabled="sceneUploadLoading">
                {{ sceneUploadLoading ? '上传中...' : '上传' }}
              </div>
              <div class="select-btn" @click="selectScene">选择</div>
            </div>
            <!-- 删除按钮 -->
            <div v-if="sceneImageHovered" class="delete-icon" @click="removeSceneImage">
              <svg-icon icon-class="guanbi" color="#64687A" :size="10" />
            </div>
            <!-- loading状态 -->
            <div v-if="sceneUploadLoading" class="scene-upload-loading">
              <div class="loading-spinner"></div>
            </div>
          </div>
          <div v-if="sceneImageUrl" class="hover-tooltip">场景图</div>
          <!-- 无图片时的占位区域 -->
          <template v-else>
            <div class="select-label">场景图</div>
            <div class="select-btn" @click="handleSceneImageUpload" :disabled="sceneUploadLoading">
              {{ sceneUploadLoading ? '上传中...' : '上传' }}
            </div>
            <div class="select-btn" @click="selectScene">选择</div>
          </template>
        </div>
        <div class="select-wrapper">
          <div class="select-label">主体图</div>
          <div class="select-btn" @click="handleSubjectImageUpload" :disabled="subjectUploadLoading">
            {{ subjectUploadLoading ? '上传中...' : '上传' }}
          </div>
          <div class="select-btn" @click="selectBody">选择</div>
        </div>

        <textarea v-model="subjectPrompt"
          style="color:#1C1D29;font-size:14px;padding:8px 12px;flex:1;height: 120px;resize: none;"
          class="w-full border border-gray-200 rounded-lg focus:outline-none focus:ring-1 focus:ring-blue-500 transition-all"
          placeholder="请输入提示词，描述想创作的画面内容"></textarea>
        <div :class="['send-btn', subjectPrompt.trim() === '' ? 'disabled' : '']" @click="generateMask">
          <svg-icon class="opt-icon" color="#fff" icon-class="fasong" />
        </div>
      </div>
    </div>

    <!-- 固定工具栏 -->
    <div v-if="showToolbar && imageLoaded && editType !== 'MULTI_BODY'" class="fixed-toolbar" :style="toolbarStyle" @click.stop>
      <!-- 一级工具栏 -->
      <div v-if="toolbarLevel === 1" class="toolbar-level-1">
        <div :class="['tool-btn', currentMode === 'redraw' ? 'selected' : '']" @click="switchToSecondLevel('redraw')">
          <svg-icon class="opt-icon mr-4px" icon-class="jubuzhonghui" :size="20" />局部重绘
        </div>
        <div :class="['tool-btn', currentMode === 'remove' ? 'selected' : '']" @click="switchToSecondLevel('remove')">
          <svg-icon class="opt-icon mr-4px" icon-class="xiaochu" :size="20" />消除
        </div>
      </div>

      <!-- 二级工具栏 -->
      <div v-if="toolbarLevel === 2" class="toolbar-level-1" style="gap: 6px;">
        <!-- 撤销重做按钮 -->
        <div class="tool-btn-sub tooltip-wrapper" @click="undo" :disabled="historyStep <= 0">
          <svg-icon :color="historyStep <= 0 ? '#BCBFCC' : '#64687A'" class="opt-icon" icon-class="chexiao" :size="26" />
          <div class="hover-tooltip">撤销</div>
        </div>
        
        <div class="tool-btn-sub tooltip-wrapper" @click="redo" :disabled="historyStep >= history.length - 1">
          <svg-icon :color="historyStep >= history.length - 1 ? '#BCBFCC' : '#64687A'" class="opt-icon" icon-class="zhongzuo" :size="26" />
          <div class="hover-tooltip">重做</div>
        </div>

        <div class="tool-line"></div>
        
        <!-- 智能选区按钮 -->
        <div :class="['tool-btn-sub', 'tooltip-wrapper', currentTool === 'auto-select' ? 'selected' : '']"
          @click="setTool('auto-select')">
          <svg-icon color="#64687A" class="opt-icon" icon-class="xuanqu" :size="26" />
          <div class="hover-tooltip">智能选区</div>
        </div>
          
        <div :class="['tool-btn-sub', 'tooltip-wrapper', currentTool === 'brush' ? 'selected' : '']"
          @click="setTool('brush')">
          <svg-icon color="#64687A" class="opt-icon" icon-class="huabi" :size="26" />
          <div class="hover-tooltip">画笔</div>
          </div>
          
        <div :class="['tool-btn-sub', 'tooltip-wrapper', currentTool === 'eraser' ? 'selected' : '']"
          @click="setTool('eraser')">
          <svg-icon color="#64687A" class="opt-icon" icon-class="xiangpi" :size="26" />
          <div class="hover-tooltip">橡皮擦</div>
        </div>

        <div class="tool-line"></div>

        <div style="display: flex; align-items: center;" v-if="currentTool !== 'auto-select'">
          <div class="tool-btn-sub tooltip-wrapper" @click="decreaseBrushSize" style="padding-right: 0">
            <svg-icon color="#64687A" class="opt-icon" icon-class="zuixiaohuabi" :size="26" />
            <div class="hover-tooltip">最小画笔</div>
          </div>
          
          <!-- 尺寸调节器 -->
          <div class="size-adjuster tooltip-wrapper">
            <div class="custom-slider" @mousedown="handleSliderMouseDown" @keydown="handleSliderKeyDown" tabindex="0"
              ref="sliderRef">
              <div class="slider-track">
                <div class="slider-fill" :style="{ width: fillWidth }"></div>
                <div class="slider-thumb" :class="{ 'dragging': isDragging }" :style="{ left: thumbPosition }"
                  @mousedown.stop="handleThumbMouseDown"></div>
              </div>
            </div>
            <div class="hover-tooltip">{{ brushSize }}</div>
          </div>
          
          <div class="tool-btn-sub tooltip-wrapper" @click="increaseBrushSize" style="padding-left: 0">
            <svg-icon color="#64687A" class="opt-icon" icon-class="zuidahuabi" :size="26" />
            <div class="hover-tooltip">最大画笔</div>
          </div>
        </div>

        <div v-else class="tool-btn-text">请用鼠标选择选区</div>

        <div class="tool-line"></div>

        <el-button v-if="currentMode === 'remove'" style="height: 28px;margin-left: 4px;" color="#1c1d29"
          @click="generateMask">消除</el-button>

        <div class="tool-btn-sub tooltip-wrapper close-btn" @click="closeSecondLevel">
          <svg-icon color="#BCBFCC" class="opt-icon" icon-class="guanbi" :size="20" />
          <div class="hover-tooltip">关闭</div>
          </div>
      </div>
    </div>

    <!-- 画笔预览 -->
    <div v-if="showBrushPreview" class="brush-preview" :style="brushPreviewStyle"></div>

    <!-- 角色选择弹窗 -->
    <el-dialog v-model="actorDialogVisible" title="添加角色及视图" width="800px" destroy-on-close class="actor-select-dialog"
      :show-close="false">
      <template #header="{ close, titleId, titleClass }">
        <div style="width: 756px;">
          <div class="actor-select-header-close">
            <div>添加角色和视图</div>
            <el-icon :size="16" @click="close">
              <Close />
            </el-icon>
          </div>
          <!-- 第一行：标题和新增按钮 -->
          <div class="actor-select-header">
            <div class="header-title">请选择1~5个角色添加到主体图</div>
            <el-button color="#1c1d29" @click="addActorForm" :disabled="actorForms.length >= 5">
              新增角色
            </el-button>
          </div>
        </div>
      </template>
      <div class="actor-select-content">
        <!-- 角色表单列表 -->
        <div v-for="(formItem, index) in actorForms" :key="index" class="actor-form-item">
          <!-- 选择角色 -->
          <div class="form-item">
            <div class="form-label">
              <div>选择角色<span class="required-mark">*</span></div>
              <el-button class="delete-button" v-if="actorForms.length >= 2" @click="removeActorForm(index)" link>
                <el-icon>
                  <Delete />
                </el-icon>
              </el-button>
            </div>
            <el-select v-model="formItem.actorId" placeholder="请选择角色" filterable style="width: 100%"
              @change="handleActorSelectChange(index, $event)">
              <el-option v-for="role in props.roles" :key="role.id" :label="role.actorName" :value="role.actorId" />
            </el-select>
          </div>

          <!-- 选择角色视图 -->
          <div class="form-item">
            <div class="form-label">
              <div>选择角色视图<span class="required-mark">*</span></div>
            </div>
            <el-select v-model="formItem.perspective" placeholder="请选择角色视图" filterable style="width: 100%"
              @change="handlePerspectiveChange(index, $event)">
              <el-option v-for="view in actorViews" :key="view.value" :label="view.label" :value="view.value" />
            </el-select>
          </div>

          <!-- 图片预览 -->
          <div v-if="formItem.actorId && formItem.perspective" class="actor-images-preview">
            <div class="form-label">图片预览</div>
            <div class="actor-images-grid">
              <div class="actor-image-item" v-if="formItem.perspective === 'WHOLE_BODY_FRONT'">
                <img v-if="getSelectedActor(formItem.actorId)?.wholeBodyFrontImageUrl"
                  :src="getSelectedActor(formItem.actorId).wholeBodyFrontImageUrl" class="actor-view-image" alt="主图" />
                <div v-else class="actor-view-placeholder">暂无主图</div>
              </div>

              <div class="actor-image-item" v-if="formItem.perspective === 'WHOLE_BODY_SIDE'">
                <img v-if="getSelectedActor(formItem.actorId)?.wholeBodySideImageUrl"
                  :src="getSelectedActor(formItem.actorId).wholeBodySideImageUrl" class="actor-view-image" alt="侧图" />
                <div v-else class="actor-view-placeholder">暂无侧图</div>
              </div>

              <div class="actor-image-item" v-if="formItem.perspective === 'WHOLE_BODY_BACK'">
                <img v-if="getSelectedActor(formItem.actorId)?.wholeBodyBackImageUrl"
                  :src="getSelectedActor(formItem.actorId).wholeBodyBackImageUrl" class="actor-view-image" alt="背图" />
                <div v-else class="actor-view-placeholder">暂无背图</div>
              </div>

              <div class="actor-image-item" v-if="formItem.perspective === 'HALF_BODY'">
                <img v-if="getSelectedActor(formItem.actorId)?.halfBodyImageUrl"
                  :src="getSelectedActor(formItem.actorId).halfBodyImageUrl" class="actor-view-image" alt="半身图" />
                <div v-else class="actor-view-placeholder">暂无半身图</div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <template #footer>
        <span class="dialog-footer">
          <el-button @click="actorDialogVisible = false">取消</el-button>
          <el-button color="#1c1d29" @click="handleConfirmSelectActor">
            添加角色
          </el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 场景选择弹窗 -->
    <el-dialog v-model="sceneDialogVisible" title="切换场景" width="500px" destroy-on-close>
      <el-form ref="sceneFormRef" :model="sceneForm" :rules="sceneRules" label-width="80px">
        <el-form-item label="选择场景" prop="sceneId" required>
          <el-select v-model="sceneForm.sceneId" placeholder="请选择场景" style="width: 100%" filterable
            @change="handleSceneChange">
            <el-option v-for="scene in scenes" :key="scene.id" :label="scene.sceneName" :value="scene.sceneId" />
          </el-select>
        </el-form-item>
        <el-form-item label="场景预览" prop="sceneDesc" v-if="sceneForm.sceneId">
          <el-image :src="scenes.find(item => item.sceneId === sceneForm.sceneId)?.sceneImageUrl"
            class="scene-preview-image" />
        </el-form-item>
      </el-form>

      <template #footer>
        <div class="dialog-footer">
          <el-button @click="sceneDialogVisible = false">取消</el-button>
          <el-button color="#1c1d29" @click="handleConfirmSelectScene">确定</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, computed, watch, onMounted, onUnmounted, nextTick } from 'vue'
import { ElMessage } from 'element-plus'
import { Delete, Close, CaretBottom } from '@element-plus/icons-vue'
import { uploadFile, imageMaskEdit, smartSelection, imageRemoveEdit, multiSubjectEdit, getDramaScene, getPutUrl, putUrlToOss } from '@/api/drama'
import PicUpload from '@/components/common/PicUpload.vue'

// Props定义
const props = defineProps({
  imageUrl: {
    type: String,
    required: true
  },
  width: {
    type: Number,
    default: 800
  },
  height: {
    type: Number,
    default: 600
  },
  businessId: {
    type: String,
    default: ''
  },
  businessType: {
    type: String,
    default: 'STORYBOARD'
  },
  roles: {
    type: Array,
    default: () => []
  },
  dramaId: {
    type: String,
    default: ''
  },
  isRecordExpanded: {
    type: Boolean,
    default: false
  }
})

const modelProvider = ref('JIMENG_4')
const resultNum = ref(1)

const prompt = ref('')
const subjectPrompt = ref('')

// 参考图上传状态
const hasReferenceImage = ref(false)

const imageFileKey = ref('')
const subjectFileKey = ref('')

// 处理参考图上传
const handleCoverUpload = async (fileKey) => {
  console.log('参考图上传成功，fileKey:', fileKey)

  if (editType.value === 'STORYBOARD') {
    imageFileKey.value = fileKey
    // 图像编辑模式：生成替换格式提示词
    if (!prompt.value || prompt.value.trim() === '') {
      prompt.value = '把图1中的[描述要替换的内容]替换为图2中的[描述替换目标]'
      ElMessage.success('参考图上传成功，已自动生成提示词模板，请修改具体内容')
    } else {
      ElMessage.success('参考图上传成功')
    }
  } else if (editType.value === 'MULTI_BODY') {
    subjectFileKey.value = fileKey
    // 多主体模式：标记有参考图并更新提示词
    hasReferenceImage.value = true
    updateMultiBodyPrompt()
    ElMessage.success('参考图上传成功，已更新提示词')
  }
}

// Emits定义
const emit = defineEmits(['image-loaded', 'image-dimensions-detected', 'generation-completed', 'reference-image-edit'])

// Template refs
const canvasContainer = ref(null)
const mainCanvas = ref(null)
const brushCanvas = ref(null)
const selectionCanvas = ref(null)
const antsCanvas = ref(null)
const controlCanvas = ref(null)
const autoSelectCanvas = ref(null)
const promptInput = ref(null)
const storyboardReferenceUpload = ref(null)
const multiBodyReferenceUpload = ref(null)

// Canvas相关响应式数据
const canvas = ref(null)
const ctx = ref(null)
const brushCanvasRef = ref(null)
const brushCtx = ref(null)
const selectionCanvasRef = ref(null)
const selectionCtx = ref(null)
const antsCanvasRef = ref(null)
const antsCtx = ref(null)
const controlCanvasRef = ref(null)
const controlCtx = ref(null)
const autoSelectCanvasRef = ref(null)
const autoSelectCtx = ref(null)
const image = ref(null)
const imageLoaded = ref(false)
const editType = ref('STORYBOARD')

// 图片尺寸信息
const imageDimensions = reactive({
  width: 0,
  height: 0,
  naturalWidth: 0,
  naturalHeight: 0
})

// 工具栏状态
const showToolbar = ref(false)
const toolbarLevel = ref(1) // 1: 一级工具栏, 2: 二级工具栏
const toolbarPosition = reactive({ left: '0px', top: '0px' })
const currentMode = ref(null) // 'redraw' or 'remove'

// 工具状态
const currentTool = ref(null) // 'auto-select', 'brush', 'eraser'
const brushSize = ref(10)
const isDrawing = ref(false)

// 自定义滑块相关
const sliderRef = ref(null)
const isDragging = ref(false)
const minBrushSize = 1
const maxBrushSize = 50

// 计算滑块填充宽度
const fillWidth = computed(() => {
  const percentage = ((brushSize.value - minBrushSize) / (maxBrushSize - minBrushSize)) * 100
  return `${percentage}%`
})

// 计算滑块拇指位置
const thumbPosition = computed(() => {
  const percentage = ((brushSize.value - minBrushSize) / (maxBrushSize - minBrushSize)) * 100
  return `calc(${percentage}% - 5px)` // 减去拇指宽度的一半
})

// 选区相关
const hasSelection = ref(false)
const selectionPath = ref([])
const isScanning = ref(false)

// 鼠标状态
const mousePos = reactive({ x: 0, y: 0 })
const showBrushPreview = ref(false)


const removeButtonPosition = reactive({ 
  left: '50%', 
  bottom: '20px', 
  transform: 'translateX(-50%)' 
})

// 历史记录
const history = ref([])
const historyStep = ref(-1)
const originalImageData = ref('')

// 画笔画布历史记录
const brushHistory = ref([])
const brushHistoryStep = ref(-1)

// 画笔轨迹记录
const brushStrokes = ref([])
const currentStroke = ref(null)

// 鼠标移动跟踪（用于检测纯点击）
const hasMouseMoved = ref(false)
const mouseDownPos = ref({ x: 0, y: 0 })

// 保存的掩码图数据
const savedMaskImageData = ref(null)

// 智能选区相关
const smartSelectionMasks = ref([]) // 存储智能选区返回的掩码图列表
const isSmartSelectionMode = ref(false) // 是否处于智能选区模式

// 角色选择相关
const actorDialogVisible = ref(false)
const selectedActors = ref([]) // 存储选择的角色图片信息
const actorForms = ref([]) // 角色表单数组
const showExpandedImages = ref(false) // 是否显示展开状态的图片
const showDeleteIcon = ref([]) // 控制每个图片的删除图标显示
const showReferenceDeleteIcon = ref(false) // 控制参考图删除图标显示
const showSceneDeleteIcon = ref(false) // 控制场景图删除图标显示

// 场景选择相关
const sceneDialogVisible = ref(false)
const scenes = ref([]) // 存储场景列表
const sceneFormRef = ref(null)
const sceneForm = reactive({
  sceneId: '',
  sceneName: '',
  sceneResKey: '',
  previewUrl: ''
})
const sceneRules = {
  sceneId: [
    { required: true, message: '请选择场景', trigger: 'change' }
  ]
}
const sceneImageUrl = ref('') // 当前选中的场景图片URL
const sceneResKey = ref('') // 场景图片的资源key

// 上传相关状态
const sceneUploadLoading = ref(false)
const subjectUploadLoading = ref(false)
const sceneImageHovered = ref(false)

// 角色视图选项
const actorViews = [
  { value: 'WHOLE_BODY_FRONT', label: '主图' },
  { value: 'WHOLE_BODY_SIDE', label: '侧图' },
  { value: 'WHOLE_BODY_BACK', label: '背图' },
  { value: 'HALF_BODY', label: '半身图' }
]

// 边界线相关
const antsAnimation = ref(null)

// 图片缩放相关
const imageScale = ref(1)  // 图片缩放比例
const imageOffset = reactive({ x: 0, y: 0 })  // 图片偏移位置
const controlPoints = ref([])  // 控制点数组
const activeControlPoint = ref(null)  // 当前激活的控制点
const isDraggingControl = ref(false)  // 是否正在拖拽控制点
const isDraggingImage = ref(false)  // 是否正在拖拽图片
const showControlPoints = ref(true)  // 是否显示控制点
const lastMousePos = reactive({ x: 0, y: 0 })  // 上次鼠标位置


// 计算属性
const currentModeText = computed(() => {
  return currentMode.value === 'redraw' ? '局部重绘' : '消除'
})

const canvasWidth = computed(() => {
  return window.innerWidth - 100 - 16
})

const canvasHeight = computed(() => {
  return window.innerHeight - 180 - 16
})

const brushPreviewStyle = computed(() => {
  return {
    left: `${mousePos.x - brushSize.value / 2}px`,
    top: `${mousePos.y - brushSize.value / 2}px`,
    width: `${brushSize.value}px`,
    height: `${brushSize.value}px`
  }
})

// 扫光loading样式计算
const scanningOverlayStyle = computed(() => {
  if (!imageLoaded.value) {
    return { display: 'none' }
  }

  // 计算图片在画布中的实际位置和尺寸
  const { drawX, drawY, drawWidth, drawHeight } = calculateImageDimensions()

  // 应用缩放和平移
  const scaledWidth = drawWidth * imageScale.value
  const scaledHeight = drawHeight * imageScale.value
  const scaledX = drawX + (drawWidth - scaledWidth) / 2 + imageOffset.x
  const scaledY = drawY + (drawHeight - scaledHeight) / 2 + imageOffset.y

  return {
    position: 'absolute',
    left: `${scaledX}px`,
    top: `${scaledY}px`,
    width: `${scaledWidth}px`,
    height: `${scaledHeight}px`,
    borderRadius: '8px',
    overflow: 'hidden'
  }
})

// 模式输入框样式计算
const modeWrapperStyle = computed(() => {
  return {
    transform: props.isRecordExpanded ? 'translateX(-110px)' : 'translateX(0)',
    transition: 'transform 0.3s ease'
  }
})

// canvas容器样式计算
const canvasContainerStyle = computed(() => {
  return {
    transform: props.isRecordExpanded ? 'translateX(-110px)' : 'translateX(0)',
    transition: 'transform 0.3s ease'
  }
})

// 工具栏样式计算
const toolbarStyle = computed(() => {
  if (!imageLoaded.value) {
    return {}
  }

  // 计算图片在画布中的实际位置和尺寸
  const { drawX, drawY, drawWidth, drawHeight } = calculateImageDimensions()

  // 应用缩放和平移
  const scaledWidth = drawWidth * imageScale.value
  const scaledHeight = drawHeight * imageScale.value
  const scaledX = drawX + (drawWidth - scaledWidth) / 2 + imageOffset.x
  const scaledY = drawY + (drawHeight - scaledHeight) / 2 + imageOffset.y

  // 估算工具栏高度（根据实际工具栏内容调整）
  const toolbarHeight = toolbarLevel.value === 1 ? 50 : 70 // 一级工具栏约50px，二级工具栏约70px

  // 计算工具栏位置：图片下方8px，水平居中
  let toolbarTop = scaledY + scaledHeight + 8
  const toolbarLeft = scaledX + scaledWidth / 2

  // 确保工具栏不会超出画布边界
  const canvasWidth = canvas.value?.width || window.innerWidth
  const canvasHeight = canvas.value?.height || window.innerHeight

  // 限制工具栏在画布范围内
  let finalLeft = toolbarLeft
  if (finalLeft < 50) finalLeft = 50 // 左边界
  if (finalLeft > canvasWidth - 50) finalLeft = canvasWidth - 50 // 右边界

  // 垂直方向边界检查
  let finalTop = toolbarTop

  // 计算工具栏底部位置
  const toolbarBottom = toolbarTop + toolbarHeight

  // 如果工具栏底部超出画布底部，则调整位置使工具栏底部与画布底部对齐
  if (toolbarBottom > canvasHeight) {
    finalTop = canvasHeight - toolbarHeight
  }

  // 如果上方空间也不够（工具栏顶部会超出画布），则确保工具栏至少显示在画布顶部
  if (finalTop < 0) {
    finalTop = 0
  }

  // 计算平移偏移量
  const translateOffset = props.isRecordExpanded ? -110 : 0

  return {
    top: `${finalTop}px`,
    left: `${finalLeft}px`,
    transform: `translateX(calc(-50% + ${translateOffset}px))`, // 水平居中 + 记录面板偏移
    transition: 'transform 0.3s ease'
  }
})

// 初始化Canvas
const initCanvas = () => {
  canvas.value = mainCanvas.value
  ctx.value = canvas.value.getContext('2d')
  brushCanvasRef.value = brushCanvas.value
  brushCtx.value = brushCanvasRef.value.getContext('2d')
  selectionCanvasRef.value = selectionCanvas.value
  selectionCtx.value = selectionCanvasRef.value.getContext('2d')
  antsCanvasRef.value = antsCanvas.value
  antsCtx.value = antsCanvasRef.value.getContext('2d')
  controlCanvasRef.value = controlCanvas.value
  controlCtx.value = controlCanvasRef.value.getContext('2d')
  autoSelectCanvasRef.value = autoSelectCanvas.value
  autoSelectCtx.value = autoSelectCanvasRef.value.getContext('2d')
  
  // 设置画布尺寸：窗口宽度 * (屏幕高度 - 68)
  setCanvasSize(canvasWidth.value, canvasHeight.value)
}

// 设置画布尺寸
const setCanvasSize = (width, height) => {
  // 设置画布实际尺寸
  canvas.value.width = width
  canvas.value.height = height
  brushCanvasRef.value.width = width
  brushCanvasRef.value.height = height
  selectionCanvasRef.value.width = width
  selectionCanvasRef.value.height = height
  antsCanvasRef.value.width = width
  antsCanvasRef.value.height = height
  controlCanvasRef.value.width = width
  controlCanvasRef.value.height = height
  autoSelectCanvasRef.value.width = width
  autoSelectCanvasRef.value.height = height
  
  // 设置画布显示样式
  canvas.value.style.width = `${width}px`
  canvas.value.style.height = `${height}px`
  brushCanvasRef.value.style.width = `${width}px`
  brushCanvasRef.value.style.height = `${height}px`
  selectionCanvasRef.value.style.width = `${width}px`
  selectionCanvasRef.value.style.height = `${height}px`
  antsCanvasRef.value.style.width = `${width}px`
  antsCanvasRef.value.style.height = `${height}px`
  controlCanvasRef.value.style.width = `${width}px`
  controlCanvasRef.value.style.height = `${height}px`
  autoSelectCanvasRef.value.style.width = `${width}px`
  autoSelectCanvasRef.value.style.height = `${height}px`
}

// 计算图片显示尺寸和位置
const calculateImageDimensions = () => {
  const canvasWidth = canvas.value.width
  const canvasHeight = canvas.value.height
  // 使用实际图片尺寸
  const imageWidth = image.value.width
  const imageHeight = image.value.height

  // 计算图片的原始宽高比
  const imageRatio = imageWidth / imageHeight

  // 图片高度 = 画布高度 - 上下边距(82px * 2)
  const availableHeight = canvasHeight - 82 * 2
  const drawHeight = Math.min(availableHeight, canvasHeight * 0.8) // 最大不超过画布80%

  // 根据高度计算宽度，保持原始比例
  const drawWidth = drawHeight * imageRatio

  // 如果计算出的宽度超过画布宽度，则需要调整
  if (drawWidth > canvasWidth) {
    const scaleFactor = canvasWidth / drawWidth
    const finalWidth = canvasWidth
    const finalHeight = drawHeight * scaleFactor

    // 居中显示
    const drawX = 0
    const drawY = (canvasHeight - finalHeight) / 2

    return { drawX, drawY, drawWidth: finalWidth, drawHeight: finalHeight }
  }

  // 居中显示
  const drawX = (canvasWidth - drawWidth) / 2
  const drawY = (canvasHeight - drawHeight) / 2

  return { drawX, drawY, drawWidth, drawHeight }
}

// 绘制图片到画布
const drawImage = () => {
  if (!imageLoaded.value || !ctx.value) return

  ctx.value.clearRect(0, 0, canvas.value.width, canvas.value.height)

  // 计算图片在画布中的位置和尺寸（保持比例，居中显示）
  const { drawX, drawY, drawWidth, drawHeight } = calculateImageDimensions()

  // 应用缩放和平移
  const scaledWidth = drawWidth * imageScale.value
  const scaledHeight = drawHeight * imageScale.value
  const scaledX = drawX + (drawWidth - scaledWidth) / 2 + imageOffset.x
  const scaledY = drawY + (drawHeight - scaledHeight) / 2 + imageOffset.y

  ctx.value.drawImage(image.value, scaledX, scaledY, scaledWidth, scaledHeight)

  // 更新画笔画布遮罩
  updateBrushCanvasMask()

  // 更新控制点位置
  updateControlPoints()

  // 只有在显示控制点时才绘制
  if (showControlPoints.value) {
    drawControlPoints()
  }
}

// 保存历史记录
const saveHistory = () => {
  // 保存主画布历史
  historyStep.value++
  if (historyStep.value < history.value.length) {
    history.value.length = historyStep.value
  }
  history.value.push(canvas.value.toDataURL())

  // 保存画笔画布历史
  brushHistoryStep.value++
  if (brushHistoryStep.value < brushHistory.value.length) {
    brushHistory.value.length = brushHistoryStep.value
  }
  brushHistory.value.push(brushCanvasRef.value.toDataURL())
}

// 加载图片
const loadImage = () => {
  if (!canvas.value) return
  
  image.value = new Image()
  image.value.crossOrigin = 'anonymous'
  
  image.value.onload = () => {
    // 记录图片尺寸信息
    imageDimensions.naturalWidth = image.value.width
    imageDimensions.naturalHeight = image.value.height
    console.log(image.value.width, image.value.height)
    
    // 使用传入的图片尺寸
    imageDimensions.width = image.value.width
    imageDimensions.height = image.value.height
    
    imageLoaded.value = true
    drawImage()
    
    // 保存原始图片状态
    originalImageData.value = canvas.value.toDataURL()
    
    // 初始化画笔历史记录（空的画笔画布状态）
    brushHistory.value = [brushCanvasRef.value.toDataURL()]
    brushHistoryStep.value = 0

    saveHistory()

    // 显示控制点
    updateControlPoints()

    // 图片加载完成后自动显示工具栏
    showToolbar.value = true
    toolbarLevel.value = 1

    // 触发事件，传递图片尺寸信息
    emit('image-loaded')
    emit('image-dimensions-detected', {
      naturalWidth: imageDimensions.naturalWidth,
      naturalHeight: imageDimensions.naturalHeight,
      displayWidth: imageDimensions.width,
      displayHeight: imageDimensions.height
    })
  }
  
  image.value.onerror = (e) => {
    console.error('Image load error:', e)
  }
  
  image.value.src = props.imageUrl
}

// 监听imageUrl变化
watch(() => props.imageUrl, (newUrl) => {
  if (newUrl && canvas.value) {
    // 重置原始图片数据
    originalImageData.value = ''
    loadImage()
  }
})

// 监听modelProvider变化，当切换为GEMINI时，如果resultNum不为1，重置为1
watch(modelProvider, (newValue) => {
  if (newValue === 'GEMINI' && resultNum.value !== 1) {
    resultNum.value = 1
  }
})

// 处理画布点击
const handleCanvasClick = (event) => {
  const rect = canvas.value.getBoundingClientRect()
  const x = event.clientX - rect.left
  const y = event.clientY - rect.top

  if (currentTool.value === 'auto-select') {
    if (isSmartSelectionMode.value && smartSelectionMasks.value.length > 0) {
      // 智能选区模式下，点击选择对应的掩码图
      selectMaskAtPosition(x, y)
    } else {
      // 传统自动选区
      performAutoSelect(x, y)
    }
  }
  // 工具栏现在在图片加载后自动显示，不需要点击时再显示
}

// 显示悬浮工具栏
const showFloatingToolbar = (event) => {
  const rect = canvasContainer.value.getBoundingClientRect()
  toolbarPosition.left = `${event.clientX - rect.left}px`
  toolbarPosition.top = `${event.clientY - rect.top - 50}px`
  showToolbar.value = true
  toolbarLevel.value = 1
}

// 切换到二级工具栏
const switchToSecondLevel = (mode) => {
  currentMode.value = mode
  toolbarLevel.value = 2
}

// 关闭二级工具栏
const closeSecondLevel = () => {
  toolbarLevel.value = 1
  currentTool.value = null
  showBrushPreview.value = false
  clearSelection()
  // 清除画笔轨迹记录
  brushStrokes.value = []
  currentStroke.value = null
  
  // 清除智能选区相关状态
  smartSelectionMasks.value = []
  isSmartSelectionMode.value = false
}

// 设置工具
const setTool = async (tool) => {
  currentTool.value = tool
  
  if (tool === 'auto-select') {
    await performSmartSelection()
  } else if (tool === 'brush' || tool === 'eraser') {
    showBrushPreview.value = true
  } else {
    showBrushPreview.value = false
    isSmartSelectionMode.value = false
  }
}

// 开始自动选区
const startAutoSelect = () => {
  isScanning.value = true
  
  // 模拟AI处理时间
  setTimeout(() => {
    isScanning.value = false
    // 这里可以集成实际的AI选区算法
  }, 2000)
}

// 执行自动选区
const performAutoSelect = (x, y) => {
  if (!isScanning.value && currentTool.value === 'auto-select') {
    // 模拟智能选区结果
    createMockSelection(x, y)
    hasSelection.value = true
  }
}

// 执行智能选区
const performSmartSelection = async () => {
  if (!imageLoaded.value) {
    ElMessage.warning('请先加载图片')
    return
  }

  try {
    // 启用扫光loading
    isScanning.value = true
    ElMessage.info('正在生成智能选区...')
    
    // 从原始imageUrl获取原图并上传
    const imageBlob = await fetch(props.imageUrl)
      .then(res => res.blob())
    const imageFile = new File([imageBlob], 'original-image.png', { type: imageBlob.type || 'image/png' })
    
    console.log(`智能选区原图 - 来源: ${props.imageUrl}`)
    console.log(`智能选区原图 - 文件大小: ${(imageFile.size / 1024 / 1024).toFixed(2)}MB, 类型: ${imageFile.type}`)
    
    // 上传图片获取fileKey
    const uploadResult = await uploadFile(imageFile)
    const fileKey = uploadResult.data.fileKey
    console.log(`智能选区原图上传成功 - fileKey: ${fileKey}`)
    
    // 调用智能选区接口
    const smartSelectionParams = {
      businessType: props.businessType,
      businessId: props.businessId,
      businessImageResKey: fileKey,
      prompt: prompt.value.trim()
    }
    
    const result = (await smartSelection(smartSelectionParams)).data.data
    console.log(result)
    
    if (result.length > 0) {
      // 存储掩码图列表
      smartSelectionMasks.value = result.map((base64Data, index) => ({
        id: index,
        base64: base64Data,
        imageData: null // 将在需要时转换
      }))
      
      // 进入智能选区模式
      isSmartSelectionMode.value = true
      
      // 清除画笔画布，准备显示智能选区结果
      brushCtx.value.clearRect(0, 0, brushCanvasRef.value.width, brushCanvasRef.value.height)
      
      ElMessage.success(`智能选区完成，共生成${result.length}个候选区域，请点击图片选择`)
      console.log('智能选区结果:', smartSelectionMasks.value)
    } else {
      ElMessage.warning('未生成有效的选区，请尝试调整提示词')
    }
    
  } catch (error) {
    console.error('智能选区失败:', error)
    ElMessage.error('智能选区失败: ' + (error.message || '未知错误'))
  } finally {
    // 关闭扫光loading
    isScanning.value = false
  }
}

// 根据保存的掩码数据执行自动选区（保留旧逻辑作为备用）
const performAutoSelectFromMask = () => {
  if (!savedMaskImageData.value) {
    ElMessage.warning('请先进行擦除操作生成掩码')
    return
  }

  console.log('执行自动选区，使用保存的掩码数据')
  
  // 清除自动选区画布
  autoSelectCtx.value.clearRect(0, 0, autoSelectCanvasRef.value.width, autoSelectCanvasRef.value.height)
  
  // 根据掩码数据绘制白色区域
  drawAutoSelectFromMask()
  
  // 更新选区状态
  hasSelection.value = true
  
  ElMessage.success('自动选区完成')
}

// 根据掩码数据绘制自动选区
const drawAutoSelectFromMask = () => {
  if (!savedMaskImageData.value || !autoSelectCtx.value) return
  
  const maskData = savedMaskImageData.value
  
  // 获取当前图片的显示信息
  const { drawX, drawY, drawWidth, drawHeight } = calculateImageDimensions()
  const currentScaledWidth = drawWidth * imageScale.value
  const currentScaledHeight = drawHeight * imageScale.value
  const currentScaledX = drawX + (drawWidth - currentScaledWidth) / 2 + imageOffset.x
  const currentScaledY = drawY + (drawHeight - currentScaledHeight) / 2 + imageOffset.y
  
  // 计算缩放比例（从掩码生成时的尺寸到当前显示尺寸）
  const scaleX = currentScaledWidth / maskData.scaledWidth
  const scaleY = currentScaledHeight / maskData.scaledHeight
  
  // 计算位置偏移
  const offsetX = currentScaledX - maskData.scaledX * scaleX
  const offsetY = currentScaledY - maskData.scaledY * scaleY
  
  // 设置绘制样式
  autoSelectCtx.value.fillStyle = 'rgba(255, 255, 255, 0.7)' // 半透明白色
  autoSelectCtx.value.strokeStyle = 'rgba(255, 255, 255, 1)' // 白色边框
  autoSelectCtx.value.lineWidth = 2
  
  // 采样步长，避免逐像素遍历影响性能
  const step = 2
  
  // 遍历掩码数据，绘制白色区域
  const imageData = maskData.imageData
  const data = imageData.data
  
  for (let y = 0; y < maskData.height; y += step) {
    for (let x = 0; x < maskData.width; x += step) {
      const index = (y * maskData.width + x) * 4
      const red = data[index]
      
      // 如果是白色像素（掩码区域）
      if (red > 128) {
        // 计算在当前显示中的位置
        const displayX = (x / maskData.width) * currentScaledWidth + currentScaledX
        const displayY = (y / maskData.height) * currentScaledHeight + currentScaledY
        
        // 绘制小方块
        autoSelectCtx.value.fillRect(displayX, displayY, step * scaleX, step * scaleY)
      }
    }
  }
  
  console.log('自动选区绘制完成')
}

// 根据点击位置选择对应的掩码图
const selectMaskAtPosition = async (x, y) => {
  if (!smartSelectionMasks.value.length) {
    return
  }

  console.log(`点击位置: (${x}, ${y})，开始查找对应掩码`)
  
  // 检查点击位置是否在图片区域内
  if (!isPointInImageArea(x, y)) {
    ElMessage.info('请点击图片区域内')
    return
  }
  
  // 计算图片在画布中的位置和尺寸
  const { drawX, drawY, drawWidth, drawHeight } = calculateImageDimensions()
  const scaledWidth = drawWidth * imageScale.value
  const scaledHeight = drawHeight * imageScale.value
  const scaledX = drawX + (drawWidth - scaledWidth) / 2 + imageOffset.x
  const scaledY = drawY + (drawHeight - scaledHeight) / 2 + imageOffset.y
  
  // 将画布坐标转换为图片内的相对坐标
  const relativeX = (x - scaledX) / scaledWidth
  const relativeY = (y - scaledY) / scaledHeight
  
  // 遍历所有掩码图，找到对应位置为白色的掩码
  for (let i = 0; i < smartSelectionMasks.value.length; i++) {
    const mask = smartSelectionMasks.value[i]
    
    // 如果还没有转换为ImageData，先转换
    if (!mask.imageData) {
      mask.imageData = await base64ToImageData(mask.base64)
    }
    
    if (mask.imageData) {
      // 计算在掩码图中的像素位置
      const maskX = Math.floor(relativeX * mask.imageData.width)
      const maskY = Math.floor(relativeY * mask.imageData.height)
      
      // 检查该位置是否为白色（掩码区域）
      if (isWhitePixelAtPosition(mask.imageData, maskX, maskY)) {
        console.log(`找到匹配的掩码图: ${i}`)
        
        // 清除之前的画笔绘制
        brushCtx.value.clearRect(0, 0, brushCanvasRef.value.width, brushCanvasRef.value.height)
        
        // 在画笔画布上绘制选中的掩码图
        drawMaskOnBrushCanvas(mask.imageData)
        
        // 更新选区状态
        hasSelection.value = true
        
        return
      }
    }
  }
  
  ElMessage.info('该位置没有检测到选区')
}

// 将base64转换为ImageData
const base64ToImageData = (base64Data) => {
  return new Promise((resolve) => {
    const img = new Image()
    img.onload = () => {
      const tempCanvas = document.createElement('canvas')
      const tempCtx = tempCanvas.getContext('2d')
      tempCanvas.width = img.width
      tempCanvas.height = img.height
      tempCtx.drawImage(img, 0, 0)
      const imageData = tempCtx.getImageData(0, 0, img.width, img.height)
      resolve(imageData)
    }
    img.onerror = () => resolve(null)
    img.src = `data:image/png;base64,${base64Data}`
  })
}

// 检查指定位置是否为白色像素
const isWhitePixelAtPosition = (imageData, x, y) => {
  if (x < 0 || x >= imageData.width || y < 0 || y >= imageData.height) {
    return false
  }
  
  const index = (y * imageData.width + x) * 4
  const red = imageData.data[index]
  const green = imageData.data[index + 1]
  const blue = imageData.data[index + 2]
  const alpha = imageData.data[index + 3]
  
  // 检查是否为白色（或接近白色）
  return red > 200 && green > 200 && blue > 200 && alpha > 128
}

// 在画笔画布上绘制掩码图
const drawMaskOnBrushCanvas = (maskImageData) => {
  if (!brushCtx.value || !maskImageData) return
  
  // 设置图片区域裁剪
  setImageClipping()
  
  // 获取当前图片的显示信息
  const { drawX, drawY, drawWidth, drawHeight } = calculateImageDimensions()
  const scaledWidth = drawWidth * imageScale.value
  const scaledHeight = drawHeight * imageScale.value
  const scaledX = drawX + (drawWidth - scaledWidth) / 2 + imageOffset.x
  const scaledY = drawY + (drawHeight - scaledHeight) / 2 + imageOffset.y
  
  // 设置画笔绘制样式
  brushCtx.value.globalCompositeOperation = 'source-over'
  brushCtx.value.globalAlpha = 1.0
  brushCtx.value.fillStyle = 'rgba(100, 112, 250, 1)' // 与画笔相同的颜色
  
  // 采样步长，避免逐像素遍历影响性能
  const step = 2
  
  // 遍历掩码数据，在画笔画布上绘制
  const data = maskImageData.data
  
  for (let y = 0; y < maskImageData.height; y += step) {
    for (let x = 0; x < maskImageData.width; x += step) {
      const index = (y * maskImageData.width + x) * 4
      const red = data[index]
      const green = data[index + 1]
      const blue = data[index + 2]
      const alpha = data[index + 3]
      
      // 如果是白色像素（掩码区域）
      if (red > 200 && green > 200 && blue > 200 && alpha > 128) {
        // 计算在当前显示中的位置
        const displayX = (x / maskImageData.width) * scaledWidth + scaledX
        const displayY = (y / maskImageData.height) * scaledHeight + scaledY
        
        // 在画笔画布上绘制小方块
        brushCtx.value.fillRect(displayX, displayY, step * (scaledWidth / maskImageData.width), step * (scaledHeight / maskImageData.height))
      }
    }
  }
  
  // 恢复画笔上下文状态
  restoreBrushContext()
  
  // 生成对应的画笔轨迹记录，用于后续的掩码生成
  generateBrushStrokesFromMask(maskImageData)
  
  // 显示边界线
  showBoundaryLine()
  
  console.log('掩码图已绘制到画笔画布并生成画笔轨迹')
}

// 从掩码图生成画笔轨迹记录
const generateBrushStrokesFromMask = (maskImageData) => {
  // 清除之前的画笔轨迹
  brushStrokes.value = []
  
  // 获取当前图片的显示信息
  const { drawX, drawY, drawWidth, drawHeight } = calculateImageDimensions()
  const scaledWidth = drawWidth * imageScale.value
  const scaledHeight = drawHeight * imageScale.value
  const scaledX = drawX + (drawWidth - scaledWidth) / 2 + imageOffset.x
  const scaledY = drawY + (drawHeight - scaledHeight) / 2 + imageOffset.y
  
  const data = maskImageData.data
  const points = []
  
  // 采样步长
  const step = 4
  
  // 遍历掩码数据，收集白色像素点
  for (let y = 0; y < maskImageData.height; y += step) {
    for (let x = 0; x < maskImageData.width; x += step) {
      const index = (y * maskImageData.width + x) * 4
      const red = data[index]
      const green = data[index + 1]
      const blue = data[index + 2]
      const alpha = data[index + 3]
      
      // 如果是白色像素（掩码区域）
      if (red > 200 && green > 200 && blue > 200 && alpha > 128) {
        // 计算在当前显示中的位置
        const displayX = (x / maskImageData.width) * scaledWidth + scaledX
        const displayY = (y / maskImageData.height) * scaledHeight + scaledY
        
        points.push({ x: displayX, y: displayY })
      }
    }
  }
  
  // 如果有点，创建一个画笔轨迹
  if (points.length > 0) {
    const brushStroke = {
      points: points,
      brushSize: 10, // 默认画笔大小
      tool: 'brush'
    }
    
    brushStrokes.value.push(brushStroke)
    console.log(`从掩码图生成了包含${points.length}个点的画笔轨迹`)
  }
}

// 在画布上绘制掩码图（保留旧方法作为备用）
const drawMaskOnCanvas = (maskImageData) => {
  if (!autoSelectCtx.value || !maskImageData) return
  
  // 获取当前图片的显示信息
  const { drawX, drawY, drawWidth, drawHeight } = calculateImageDimensions()
  const scaledWidth = drawWidth * imageScale.value
  const scaledHeight = drawHeight * imageScale.value
  const scaledX = drawX + (drawWidth - scaledWidth) / 2 + imageOffset.x
  const scaledY = drawY + (drawHeight - scaledHeight) / 2 + imageOffset.y
  
  // 设置绘制样式
  autoSelectCtx.value.fillStyle = 'rgba(255, 255, 255, 0.7)' // 半透明白色
  
  // 采样步长，避免逐像素遍历影响性能
  const step = 2
  
  // 遍历掩码数据，绘制白色区域
  const data = maskImageData.data
  
  for (let y = 0; y < maskImageData.height; y += step) {
    for (let x = 0; x < maskImageData.width; x += step) {
      const index = (y * maskImageData.width + x) * 4
      const red = data[index]
      const green = data[index + 1]
      const blue = data[index + 2]
      const alpha = data[index + 3]
      
      // 如果是白色像素（掩码区域）
      if (red > 200 && green > 200 && blue > 200 && alpha > 128) {
        // 计算在当前显示中的位置
        const displayX = (x / maskImageData.width) * scaledWidth + scaledX
        const displayY = (y / maskImageData.height) * scaledHeight + scaledY
        
        // 绘制小方块
        autoSelectCtx.value.fillRect(displayX, displayY, step * (scaledWidth / maskImageData.width), step * (scaledHeight / maskImageData.height))
      }
    }
  }
  
  console.log('掩码图绘制完成')
}

// 创建模拟选区
const createMockSelection = (centerX, centerY) => {
  selectionCtx.value.clearRect(0, 0, selectionCanvasRef.value.width, selectionCanvasRef.value.height)
  
  // 绘制选区边框
  selectionCtx.value.strokeStyle = '#00ff00'
  selectionCtx.value.lineWidth = 2
  selectionCtx.value.setLineDash([5, 5])
  
  const radius = 50
  selectionCtx.value.beginPath()
  selectionCtx.value.arc(centerX, centerY, radius, 0, Math.PI * 2)
  selectionCtx.value.stroke()
  
  // 保存选区路径
  selectionPath.value = [{ x: centerX, y: centerY, radius }]
  
  console.log('Selection created at:', { centerX, centerY, radius })
}

// 清除选区
const clearSelection = () => {
  // 隐藏边界线
  hideBoundaryLine()

  // 隐藏控制点
  if (controlCtx.value) {
    controlCtx.value.clearRect(0, 0, controlCanvasRef.value.width, controlCanvasRef.value.height)
  }

  // 清除自动选区显示
  if (autoSelectCtx.value) {
    autoSelectCtx.value.clearRect(0, 0, autoSelectCanvasRef.value.width, autoSelectCanvasRef.value.height)
  }

  // 清除画笔绘制层（先恢复上下文状态再清除）
  if (brushCtx.value) {
    restoreBrushContext()
    brushCtx.value.clearRect(0, 0, brushCanvasRef.value.width, brushCanvasRef.value.height)
  }

  // 清除选区边框层
  selectionCtx.value.clearRect(0, 0, selectionCanvasRef.value.width, selectionCanvasRef.value.height)

  selectionPath.value = []
  hasSelection.value = false

}

// 鼠标事件处理
const handleMouseDown = (event) => {
  const rect = canvas.value.getBoundingClientRect()
  const x = event.clientX - rect.left
  const y = event.clientY - rect.top

  // 检查是否点击了控制点
  const controlPointIndex = getControlPointAtPosition(x, y)
  if (controlPointIndex !== -1) {
    startDragControlPoint(controlPointIndex, x, y)
    return
  }

  // 当选择画笔或橡皮擦工具时，只有在图片区域内才允许操作
  if (currentTool.value === 'brush' || currentTool.value === 'eraser') {
    // 检查是否在图片区域内
    if (isPointInImageArea(x, y)) {
      isDrawing.value = true
      hasMouseMoved.value = false

      // 记录鼠标按下的位置
      mouseDownPos.value = { x, y }

      startDrawing(event)
    }
    return
  }

  // 检查是否在图片区域内（非控制点区域）- 只有在非绘制工具时才允许平移
  if (isPointInImageArea(x, y)) {
    startDragImage(x, y)
    return
  }
}

const handleMouseMove = (event) => {
  updateMousePosition(event)

  const rect = canvas.value.getBoundingClientRect()
  const x = event.clientX - rect.left
  const y = event.clientY - rect.top

  // 如果正在拖拽控制点
  if (isDraggingControl.value) {
    dragControlPoint(x, y)
    return
  }

  // 如果正在拖拽图片
  if (isDraggingImage.value) {
    dragImage(x, y)
    return
  }

  // 根据鼠标位置设置指针样式
  if (isPointInImageArea(x, y)) {
    // 在图片区域内，根据当前状态设置指针样式
    if (isDraggingImage.value) {
      canvas.value.style.cursor = 'move'
    } else if (currentTool.value === 'brush' || currentTool.value === 'eraser') {
      canvas.value.style.cursor = 'crosshair'
    } else {
      // 检查是否在控制点（四个角）附近，并且控制点是显示状态
      const controlPointIndex = getControlPointAtPosition(x, y)
      if (controlPointIndex !== -1 && showControlPoints.value) {
        // 根据控制点位置设置缩放光标
        const cursorMap = ['nw-resize', 'ne-resize', 'sw-resize', 'se-resize']
        canvas.value.style.cursor = cursorMap[controlPointIndex]
      } else {
        // 在图片内部但不在角上，显示移动光标
        canvas.value.style.cursor = 'move'
      }
    }
  } else {
    // 在图片区域外，恢复默认指针样式
    canvas.value.style.cursor = 'default'
  }

  if (isDrawing.value && (currentTool.value === 'brush' || currentTool.value === 'eraser')) {
    // 标记鼠标已移动
    hasMouseMoved.value = true
    continueDrawing(event)
  }
}

const handleMouseUp = () => {
  // 结束控制点拖拽
  if (isDraggingControl.value) {
    endDragControlPoint()
    return
  }

  // 结束图片拖拽
  if (isDraggingImage.value) {
    endDragImage()
    return
  }

  if (isDrawing.value) {
    // 恢复画笔上下文状态（移除裁剪）
    restoreBrushContext()

    isDrawing.value = false

    // 检查是否为纯点击（没有移动）
    if (!hasMouseMoved.value) {
      if (currentTool.value === 'brush') {
        // 画一个圆形选区
        drawCircleSelection(mouseDownPos.value.x, mouseDownPos.value.y)
        // 显示边界线
        showBoundaryLine()
      } else if (currentTool.value === 'eraser') {
        // 橡皮擦纯点击操作，重新计算边界线
        const hasContent = checkIfHasSelection()
        if (hasContent) {
          hasSelection.value = true
          showBoundaryLine()
        } else {
          hasSelection.value = false
          hideBoundaryLine()
        }
      }
    } else {
      // 保存当前轨迹到历史记录（正常拖动情况）
    if (currentStroke.value && currentStroke.value.points.length > 1) {
        // 保存轨迹时记录当前图片的显示信息
        const strokeWithImageInfo = {
          ...currentStroke.value,
          originalImageInfo: getCurrentImageDisplayInfo()
        }
        brushStrokes.value.push(strokeWithImageInfo)

        // 如果是画笔工具，更新选区状态并显示边界线
      if (currentTool.value === 'brush') {
        hasSelection.value = true
          showBoundaryLine()
        }
        // 如果是橡皮擦工具，也需要重新计算边界线
        else if (currentTool.value === 'eraser') {
          // 检查是否还有选区内容
          const hasContent = checkIfHasSelection()
          if (hasContent) {
            hasSelection.value = true
            showBoundaryLine()
          } else {
            hasSelection.value = false
            hideBoundaryLine()
          }
        }
      }
    }

    currentStroke.value = null
    saveHistory()
  }
}

const handleMouseLeave = () => {
  if (isDrawing.value) {
    isDrawing.value = false
  }
  showBrushPreview.value = false

  // 恢复默认鼠标指针样式
  if (canvas.value) {
    canvas.value.style.cursor = 'default'
  }
}

// 更新鼠标位置
const updateMousePosition = (event) => {
  // 获取.image-editor的边界框来计算正确的偏移
  const editorElement = document.querySelector('.image-editor')
  if (editorElement) {
    const editorRect = editorElement.getBoundingClientRect()

    // 计算鼠标相对于.image-editor的坐标
    mousePos.x = event.clientX - editorRect.left
    mousePos.y = event.clientY - editorRect.top
  }

  if (currentTool.value === 'brush' || currentTool.value === 'eraser') {
    showBrushPreview.value = true
  }
}

// 开始绘制选区
const startDrawing = (event) => {
  const rect = canvas.value.getBoundingClientRect()
  const x = event.clientX - rect.left
  const y = event.clientY - rect.top

  console.log('Starting drawing at:', x, y)
  console.log('brushCtx available:', !!brushCtx.value)

  // 设置图片区域裁剪
  setImageClipping()

  brushCtx.value.lineWidth = brushSize.value
  brushCtx.value.lineCap = 'round'
  brushCtx.value.lineJoin = 'round'

  if (currentTool.value === 'brush') {
    console.log('Drawing with brush tool')
    // 在画笔层绘制半透明选区
    brushCtx.value.globalCompositeOperation = 'source-over'
    brushCtx.value.globalAlpha = 1.0  // 使用strokeStyle的透明度
    brushCtx.value.strokeStyle = 'rgba(100, 112, 250, 1)'

    // 开始新的画笔轨迹
    currentStroke.value = {
      points: [{ x, y }],
      brushSize: brushSize.value,
      tool: 'brush'
    }
  } else if (currentTool.value === 'eraser') {
    console.log('Drawing with eraser tool')
    // 擦除画笔层的内容
    brushCtx.value.globalCompositeOperation = 'destination-out'
    brushCtx.value.globalAlpha = 1.0

    // 开始新的橡皮擦轨迹
    currentStroke.value = {
      points: [{ x, y }],
      brushSize: brushSize.value,
      tool: 'eraser'
    }
  }

  brushCtx.value.beginPath()
  brushCtx.value.moveTo(x, y)
}

// 继续绘制选区
const continueDrawing = (event) => {
  const rect = canvas.value.getBoundingClientRect()
  const x = event.clientX - rect.left
  const y = event.clientY - rect.top
  
  // 记录轨迹点
  if (currentStroke.value) {
    currentStroke.value.points.push({ x, y })
  }
  
  // 确保每次绘制时样式正确
  if (currentTool.value === 'brush') {
    brushCtx.value.strokeStyle = 'rgba(100, 112, 250, 1)'
    brushCtx.value.globalAlpha = 1.0
  }
  
  brushCtx.value.lineTo(x, y)
  brushCtx.value.stroke()
}

// 绘制圆形选区（用于纯点击）
const drawCircleSelection = (x, y) => {
  console.log('绘制圆形选区，位置:', x, y, '画笔大小:', brushSize.value)

  // 设置图片区域裁剪
  setImageClipping()

  // 在画笔层绘制圆形选区
  brushCtx.value.globalCompositeOperation = 'source-over'

  brushCtx.value.fillStyle = 'rgba(100, 112, 250, 1.0)'  // 使用不透明颜色

  const radius = brushSize.value / 2

  brushCtx.value.beginPath()
  brushCtx.value.arc(x, y, radius, 0, Math.PI * 2)
  brushCtx.value.fill()

  // 恢复上下文状态
  restoreBrushContext()

  // 创建一个圆形画笔轨迹记录
  const circleStroke = {
    points: [{ x, y }], // 圆心点
    brushSize: brushSize.value,
    tool: 'brush',
    isCircle: true, // 标记为圆形选区
    originalImageInfo: getCurrentImageDisplayInfo() // 记录当前图片显示信息
  }

  brushStrokes.value.push(circleStroke)

  // 更新选区状态
  hasSelection.value = true

  console.log('圆形选区绘制完成')
}

// 显示静态边界线
const showBoundaryLine = () => {
  // 停止之前的动画
  if (antsAnimation.value) {
    cancelAnimationFrame(antsAnimation.value)
  }

  console.log('开始显示静态边界线')

  // 检测边界像素
  const boundaryPixels = detectBoundaryPixels()

  if (boundaryPixels.length === 0) {
    console.log('没有检测到边界像素')
    return
  }

  console.log('检测到', boundaryPixels.length, '个边界像素')

  // 清除蚂蚁线画布
  antsCtx.value.clearRect(0, 0, antsCanvasRef.value.width, antsCanvasRef.value.height)

  // 设置静态白色虚线样式
  antsCtx.value.strokeStyle = '#ffffff'  // 白色
  antsCtx.value.lineWidth = 1
  antsCtx.value.setLineDash([8, 8])  // 静态虚线
  antsCtx.value.lineDashOffset = 0  // 固定偏移，无动画

  // 绘制边界像素
  drawBoundaryAnts(boundaryPixels)
}

// 隐藏边界线
const hideBoundaryLine = () => {
  if (antsAnimation.value) {
    cancelAnimationFrame(antsAnimation.value)
    antsAnimation.value = null
  }
  
  // 清除蚂蚁线画布
  if (antsCtx.value) {
    antsCtx.value.clearRect(0, 0, antsCanvasRef.value.width, antsCanvasRef.value.height)
  }
}

// 检测边界像素
const detectBoundaryPixels = () => {
  const imageData = brushCtx.value.getImageData(0, 0, brushCanvasRef.value.width, brushCanvasRef.value.height)
  const data = imageData.data
  const width = imageData.width
  const height = imageData.height

  const boundaryPixels = []

  // 8邻域方向
  const directions = [
    [-1, -1], [-1, 0], [-1, 1],
    [0, -1], [0, 1],
    [1, -1], [1, 0], [1, 1]
  ]

  // 获取图片区域边界
  const { drawX, drawY, drawWidth, drawHeight } = calculateImageDimensions()
  const scaledWidth = drawWidth * imageScale.value
  const scaledHeight = drawHeight * imageScale.value
  const scaledX = drawX + (drawWidth - scaledWidth) / 2 + imageOffset.x
  const scaledY = drawY + (drawHeight - scaledHeight) / 2 + imageOffset.y

  const imageRect = {
    left: Math.floor(scaledX),
    top: Math.floor(scaledY),
    right: Math.ceil(scaledX + scaledWidth),
    bottom: Math.ceil(scaledY + scaledHeight)
  }

  // 步长采样以提高性能
  const step = 1

  for (let y = 0; y < height; y += step) {
    for (let x = 0; x < width; x += step) {
      // 只处理图片区域内的像素
      if (x < imageRect.left || x >= imageRect.right || y < imageRect.top || y >= imageRect.bottom) {
        continue
      }

      const index = (y * width + x) * 4
      const alpha = data[index + 3]  // alpha通道

      // 如果当前像素有内容（alpha > 0）
      if (alpha > 0) {
        let isBoundary = false

        // 检查8邻域
        for (let [dx, dy] of directions) {
          const nx = x + dx
          const ny = y + dy

          // 边界检查 - 包括图片区域边界
          if (nx < imageRect.left || nx >= imageRect.right || ny < imageRect.top || ny >= imageRect.bottom) {
            isBoundary = true
            break
          }

          const neighborIndex = (ny * width + nx) * 4
          const neighborAlpha = data[neighborIndex + 3]

          // 如果邻域中有像素没有内容（alpha = 0）
          if (neighborAlpha === 0) {
            isBoundary = true
            break
          }
        }

        if (isBoundary) {
          boundaryPixels.push({ x, y })
        }
      }
    }
  }

  return boundaryPixels
}

// 绘制边界蚂蚁线
const drawBoundaryAnts = (boundaryPixels) => {
  if (boundaryPixels.length === 0) return
  
  // 对边界像素进行分组连接
  const connectedGroups = groupBoundaryPixels(boundaryPixels)
  
  // 为每个连接组绘制蚂蚁线
  connectedGroups.forEach(group => {
    if (group.length > 1) {
      antsCtx.value.beginPath()
      antsCtx.value.moveTo(group[0].x, group[0].y)
      
      for (let i = 1; i < group.length; i++) {
        antsCtx.value.lineTo(group[i].x, group[i].y)
      }
      
      // 如果是闭合路径，连接回起点
      if (group.length > 2) {
        antsCtx.value.lineTo(group[0].x, group[0].y)
      }
      
      antsCtx.value.stroke()
    } else if (group.length === 1) {
      // 单个像素画一个小点
      antsCtx.value.fillStyle = '#ffffff'
      antsCtx.value.fillRect(group[0].x, group[0].y, 1, 1)
    }
  })
}

// 将边界像素分组连接
const groupBoundaryPixels = (pixels) => {
  if (pixels.length === 0) return []

  // 简化版本：按距离分组
  const groups = []
  const used = new Set()

  for (let i = 0; i < pixels.length; i++) {
    if (used.has(i)) continue

    const group = [pixels[i]]
    used.add(i)

    // 查找相邻的像素
    for (let j = i + 1; j < pixels.length; j++) {
      if (used.has(j)) continue

      const dx = Math.abs(pixels[i].x - pixels[j].x)
      const dy = Math.abs(pixels[i].y - pixels[j].y)

      // 如果距离很近，认为是连接的
      if (dx <= 2 && dy <= 2) {
        group.push(pixels[j])
        used.add(j)
      }
    }

    groups.push(group)
  }

  return groups
}

// 检查画笔画布上是否还有选区内容
const checkIfHasSelection = () => {
  if (!brushCtx.value) return false

  const imageData = brushCtx.value.getImageData(0, 0, brushCanvasRef.value.width, brushCanvasRef.value.height)
  const data = imageData.data

  // 检查是否有任何像素的alpha值大于0
  for (let i = 3; i < data.length; i += 4) {
    if (data[i] > 0) {
      return true
    }
  }

  return false
}

// 恢复历史记录后更新边界线显示
const updateBoundaryAfterRestore = () => {
  // 检查是否有选区内容
  const hasContent = checkIfHasSelection()

  if (hasContent) {
    hasSelection.value = true
    // 重新计算和显示边界线
    showBoundaryLine()
  } else {
    hasSelection.value = false
    // 隐藏边界线
    hideBoundaryLine()
  }
}

// 设置图片区域裁剪
const setImageClipping = () => {
  if (!brushCtx.value || !imageLoaded.value) return

  // 计算图片在画布中的位置和尺寸
  const { drawX, drawY, drawWidth, drawHeight } = calculateImageDimensions()

  // 应用缩放和平移
  const scaledWidth = drawWidth * imageScale.value
  const scaledHeight = drawHeight * imageScale.value
  const scaledX = drawX + (drawWidth - scaledWidth) / 2 + imageOffset.x
  const scaledY = drawY + (drawHeight - scaledHeight) / 2 + imageOffset.y

  // 保存当前状态并设置裁剪区域
  brushCtx.value.save()
  brushCtx.value.beginPath()
  brushCtx.value.rect(scaledX, scaledY, scaledWidth, scaledHeight)
  brushCtx.value.clip()
}

// 恢复画笔上下文状态
const restoreBrushContext = () => {
  if (brushCtx.value) {
    brushCtx.value.restore()
  }
}

// 更新画笔画布遮罩，确保选区只在图片区域内显示，并重新绘制缩放后的画笔轨迹
const updateBrushCanvasMask = () => {
  if (!brushCtx.value || !imageLoaded.value) return

  // 清除画笔画布
  brushCtx.value.clearRect(0, 0, brushCanvasRef.value.width, brushCanvasRef.value.height)

  // 如果有画笔轨迹，重新绘制它们
  if (brushStrokes.value.length > 0) {
    redrawBrushStrokes()
  }
}

// 重新绘制所有画笔轨迹，考虑当前的缩放和偏移
const redrawBrushStrokes = () => {
  if (!brushCtx.value || brushStrokes.value.length === 0) return

  // 设置图片区域裁剪
  setImageClipping()

  // 获取当前图片的显示信息
  const currentImageInfo = getCurrentImageDisplayInfo()

  brushStrokes.value.forEach(stroke => {
    // 将轨迹坐标转换为当前图片位置和缩放下的坐标
    const transformedStroke = transformStrokeToCurrentScale(stroke, currentImageInfo)

    if (transformedStroke.tool === 'brush') {
      // 设置画笔样式
      brushCtx.value.globalCompositeOperation = 'source-over'
      brushCtx.value.globalAlpha = 1.0
      brushCtx.value.strokeStyle = 'rgba(100, 112, 250, 1)'
      brushCtx.value.fillStyle = 'rgba(100, 112, 250, 1)'
      brushCtx.value.lineWidth = transformedStroke.brushSize
      brushCtx.value.lineCap = 'round'
      brushCtx.value.lineJoin = 'round'

      if (transformedStroke.isCircle && transformedStroke.points.length >= 1) {
        // 绘制圆形选区
        const point = transformedStroke.points[0]
        const radius = transformedStroke.brushSize / 2
        brushCtx.value.beginPath()
        brushCtx.value.arc(point.x, point.y, radius, 0, Math.PI * 2)
        brushCtx.value.fill()
      } else if (transformedStroke.points.length > 1) {
        // 绘制连续的线条
        brushCtx.value.beginPath()
        brushCtx.value.moveTo(transformedStroke.points[0].x, transformedStroke.points[0].y)

        for (let i = 1; i < transformedStroke.points.length; i++) {
          brushCtx.value.lineTo(transformedStroke.points[i].x, transformedStroke.points[i].y)
        }
        brushCtx.value.stroke()
      } else if (transformedStroke.points.length === 1) {
        // 绘制单点
        const point = transformedStroke.points[0]
        const radius = transformedStroke.brushSize / 2
        brushCtx.value.beginPath()
        brushCtx.value.arc(point.x, point.y, radius, 0, Math.PI * 2)
        brushCtx.value.fill()
      }
    } else if (transformedStroke.tool === 'eraser') {
      // 设置橡皮擦样式
      brushCtx.value.globalCompositeOperation = 'destination-out'
      brushCtx.value.globalAlpha = 1.0
      brushCtx.value.lineWidth = transformedStroke.brushSize
      brushCtx.value.lineCap = 'round'
      brushCtx.value.lineJoin = 'round'

      if (transformedStroke.points.length > 1) {
        brushCtx.value.beginPath()
        brushCtx.value.moveTo(transformedStroke.points[0].x, transformedStroke.points[0].y)

        for (let i = 1; i < transformedStroke.points.length; i++) {
          brushCtx.value.lineTo(transformedStroke.points[i].x, transformedStroke.points[i].y)
        }
        brushCtx.value.stroke()
      } else if (transformedStroke.points.length === 1) {
        // 橡皮擦单点
        const point = transformedStroke.points[0]
        const radius = transformedStroke.brushSize / 2
        brushCtx.value.beginPath()
        brushCtx.value.arc(point.x, point.y, radius, 0, Math.PI * 2)
        brushCtx.value.fill()
      }
    }
  })

  // 恢复画笔上下文状态
  restoreBrushContext()

  // 如果有选区，显示边界线
  if (brushStrokes.value.some(stroke => stroke.tool === 'brush')) {
    showBoundaryLine()
  }
}

// 获取当前图片的显示信息
const getCurrentImageDisplayInfo = () => {
  const { drawX, drawY, drawWidth, drawHeight } = calculateImageDimensions()
  const scaledWidth = drawWidth * imageScale.value
  const scaledHeight = drawHeight * imageScale.value
  const scaledX = drawX + (drawWidth - scaledWidth) / 2 + imageOffset.x
  const scaledY = drawY + (drawHeight - scaledHeight) / 2 + imageOffset.y

  return {
    scaledX,
    scaledY,
    scaledWidth,
    scaledHeight,
    scale: imageScale.value,
    offsetX: imageOffset.x,
    offsetY: imageOffset.y
  }
}

// 将画笔轨迹坐标转换为当前图片缩放下的坐标
const transformStrokeToCurrentScale = (originalStroke, currentImageInfo) => {
  // 如果轨迹已经存储了原始图片信息，则进行转换
  if (!originalStroke.originalImageInfo) {
    // 如果没有原始图片信息，假设它是在当前状态下绘制的
    return originalStroke
  }

  const original = originalStroke.originalImageInfo
  const current = currentImageInfo

  // 计算缩放比例
  const scaleRatioX = current.scaledWidth / original.scaledWidth
  const scaleRatioY = current.scaledHeight / original.scaledHeight

  // 计算位置偏移
  const offsetX = current.scaledX - (original.scaledX * scaleRatioX)
  const offsetY = current.scaledY - (original.scaledY * scaleRatioY)

  // 转换所有点的坐标
  const transformedPoints = originalStroke.points.map(point => ({
    x: (point.x - original.scaledX) * scaleRatioX + current.scaledX,
    y: (point.y - original.scaledY) * scaleRatioY + current.scaledY
  }))

  // 返回转换后的轨迹
  return {
    ...originalStroke,
    points: transformedPoints,
    brushSize: originalStroke.brushSize * (scaleRatioX + scaleRatioY) / 2 // 平均缩放比例
  }
}

// 更新控制点位置
const updateControlPoints = () => {
  if (!imageLoaded.value) return

  // 计算图片在画布中的实际位置和尺寸
  const { drawX, drawY, drawWidth, drawHeight } = calculateImageDimensions()

  // 计算缩放和平移后的位置和尺寸
  const scaledWidth = drawWidth * imageScale.value
  const scaledHeight = drawHeight * imageScale.value
  const scaledX = drawX + (drawWidth - scaledWidth) / 2 + imageOffset.x
  const scaledY = drawY + (drawHeight - scaledHeight) / 2 + imageOffset.y

  // 更新四个角的控制点
  controlPoints.value = [
    { x: scaledX, y: scaledY, type: 'top-left' },
    { x: scaledX + scaledWidth, y: scaledY, type: 'top-right' },
    { x: scaledX, y: scaledY + scaledHeight, type: 'bottom-left' },
    { x: scaledX + scaledWidth, y: scaledY + scaledHeight, type: 'bottom-right' }
  ]

  // 只有在显示控制点时才绘制
  if (showControlPoints.value) {
    drawControlPoints()
  }
}

// 绘制控制点
const drawControlPoints = () => {
  if (!controlCtx.value || controlPoints.value.length === 0) return

  controlCtx.value.clearRect(0, 0, controlCanvasRef.value.width, controlCanvasRef.value.height)

  const outerRadius = 8  // 外半径
  const innerRadius = 7  // 内半径
  const ringColor = '#3644E0'  // 圆环颜色
  const ringWidth = 1  // 圆环宽度

  controlPoints.value.forEach(point => {
    // 绘制外圆（实心）
    controlCtx.value.fillStyle = ringColor
    controlCtx.value.beginPath()
    controlCtx.value.arc(point.x, point.y, outerRadius, 0, Math.PI * 2)
    controlCtx.value.fill()

    // 绘制内圆（浅灰色填充，用于创建圆环效果）
    controlCtx.value.fillStyle = '#F5F6FA'
    controlCtx.value.beginPath()
    controlCtx.value.arc(point.x, point.y, innerRadius, 0, Math.PI * 2)
    controlCtx.value.fill()
  })
}

// 检查鼠标是否在控制点上
const getControlPointAtPosition = (x, y) => {
  const controlRadius = 8

  for (let i = 0; i < controlPoints.value.length; i++) {
    const point = controlPoints.value[i]
    const distance = Math.sqrt(Math.pow(x - point.x, 2) + Math.pow(y - point.y, 2))

    if (distance <= controlRadius) {
      return i
    }
  }

  return -1
}

// 检查点是否在图片区域内
const isPointInImageArea = (x, y) => {
  if (!imageLoaded.value) return false

  // 计算图片在画布中的位置和尺寸
  const { drawX, drawY, drawWidth, drawHeight } = calculateImageDimensions()

  // 应用缩放
  const scaledWidth = drawWidth * imageScale.value
  const scaledHeight = drawHeight * imageScale.value
  const scaledX = drawX + (drawWidth - scaledWidth) / 2 + imageOffset.x
  const scaledY = drawY + (drawHeight - scaledHeight) / 2 + imageOffset.y

  // 检查点是否在图片矩形区域内
  return x >= scaledX && x <= scaledX + scaledWidth &&
         y >= scaledY && y <= scaledY + scaledHeight
}


// 开始拖拽控制点
const startDragControlPoint = (pointIndex, mouseX, mouseY) => {
  activeControlPoint.value = pointIndex
  isDraggingControl.value = true
  lastMousePos.x = mouseX
  lastMousePos.y = mouseY
}

// 拖拽控制点进行缩放
const dragControlPoint = (mouseX, mouseY) => {
  if (!isDraggingControl.value || activeControlPoint.value === null) return

  // 计算画布中心点
  const centerX = canvas.value.width / 2
  const centerY = canvas.value.height / 2

  // 计算当前鼠标位置到画布中心的距离
  const currentDistanceToCenter = Math.sqrt(
    Math.pow(mouseX - centerX, 2) +
    Math.pow(mouseY - centerY, 2)
  )

  // 计算上一次鼠标位置到画布中心的距离
  const lastDistanceToCenter = Math.sqrt(
    Math.pow(lastMousePos.x - centerX, 2) +
    Math.pow(lastMousePos.y - centerY, 2)
  )

  // 计算距离变化
  const distanceChange = currentDistanceToCenter - lastDistanceToCenter

  // 根据距离变化调整缩放
  const scaleFactor = 1 + (Math.abs(distanceChange) * 0.005)

  if (distanceChange > 0) {
    // 距离增加，鼠标远离中心，向外拖拽，放大
    imageScale.value *= scaleFactor
  } else if (distanceChange < 0) {
    // 距离减少，鼠标靠近中心，向内拖拽，缩小
    imageScale.value /= scaleFactor
  }

  // 限制缩放范围
  imageScale.value = Math.max(0.1, Math.min(5, imageScale.value))

  lastMousePos.x = mouseX
  lastMousePos.y = mouseY

  // 重新绘制图片和控制点
  drawImage()
}

// 结束拖拽
const endDragControlPoint = () => {
  isDraggingControl.value = false
  activeControlPoint.value = null

  // 恢复画笔上下文状态
  restoreBrushContext()
}

// 开始拖拽图片
const startDragImage = (mouseX, mouseY) => {
  console.log('开始拖拽图片')
  isDraggingImage.value = true
  lastMousePos.x = mouseX
  lastMousePos.y = mouseY

  // 隐藏控制点
  showControlPoints.value = false

  // 清除控制点画布
  if (controlCtx.value) {
    controlCtx.value.clearRect(0, 0, canvas.value.width, canvas.value.height)
  }

  drawImage()

  // 改变鼠标样式
  if (canvas.value) {
    canvas.value.style.cursor = 'move'
  }
}

// 拖拽图片
const dragImage = (mouseX, mouseY) => {
  if (!isDraggingImage.value) return

  const dx = mouseX - lastMousePos.x
  const dy = mouseY - lastMousePos.y

  // 更新图片偏移（鼠标移动的反方向）
  imageOffset.x += dx
  imageOffset.y += dy

  lastMousePos.x = mouseX
  lastMousePos.y = mouseY

  // 重新绘制图片
  drawImage()
}

// 结束拖拽图片
const endDragImage = () => {
  console.log('结束拖拽图片')
  isDraggingImage.value = false

  // 显示控制点
  showControlPoints.value = true
  drawImage()

  // 恢复画笔上下文状态
  restoreBrushContext()

  // 恢复鼠标样式
  if (canvas.value) {
    canvas.value.style.cursor = 'crosshair'
  }
}



// 计算选区边界
const calculateSelectionBoundary = () => {
  if (brushStrokes.value.length === 0) return null
  
  // 计算所有画笔轨迹的边界框
  let minX = Infinity, minY = Infinity
  let maxX = -Infinity, maxY = -Infinity
  
  brushStrokes.value.forEach(stroke => {
    if (stroke.tool === 'brush') {
      stroke.points.forEach(point => {
        const radius = stroke.brushSize / 2
        minX = Math.min(minX, point.x - radius)
        minY = Math.min(minY, point.y - radius)
        maxX = Math.max(maxX, point.x + radius)
        maxY = Math.max(maxY, point.y + radius)
      })
    }
  })
  
  // 添加边距
  const padding = 3
  return {
    x: minX - padding,
    y: minY - padding,
    width: maxX - minX + padding * 2,
    height: maxY - minY + padding * 2
  }
}







// 执行局部重绘
const executeRedraw = () => {
  if (!hasSelection.value) return
  
  // 模拟重绘完成
  ElMessage.success('重绘完成')
  clearSelection()
}

// 执行消除
const executeRemove = () => {
  if (!hasSelection.value) {
    console.log('No selection for removal')
    return
  }
  
  console.log('Executing removal with brush strokes:', brushStrokes.value.length)
  
  // 保存当前的绘图状态
  const originalCompositeOperation = ctx.value.globalCompositeOperation
  
  // 直接使用画笔轨迹进行消除
  brushStrokes.value.forEach((stroke, index) => {
    if (stroke.tool === 'brush') {
      console.log(`消除画笔轨迹 ${index}:`, stroke.points.length, '点')
      
      ctx.value.globalCompositeOperation = 'destination-out'
      ctx.value.fillStyle = 'rgba(0,0,0,1)'
      
      if (stroke.isCircle && stroke.points.length >= 1) {
        // 处理圆形选区消除
        const point = stroke.points[0]
        const radius = stroke.brushSize / 2
        
        ctx.value.beginPath()
        ctx.value.arc(point.x, point.y, radius, 0, Math.PI * 2)
        ctx.value.fill()
      } else if (stroke.points.length > 1) {
        // 处理线条消除
        ctx.value.lineWidth = stroke.brushSize
        ctx.value.lineCap = 'round'
        ctx.value.lineJoin = 'round'
        
        ctx.value.beginPath()
        ctx.value.moveTo(stroke.points[0].x, stroke.points[0].y)
        
        for (let i = 1; i < stroke.points.length; i++) {
          ctx.value.lineTo(stroke.points[i].x, stroke.points[i].y)
        }
        ctx.value.stroke()
      }
    }
  })
  
  // 处理传统的圆形选区消除（兼容旧逻辑）
  if (selectionPath.value.length > 0) {
  selectionPath.value.forEach((selection, index) => {
      console.log(`Removing traditional selection ${index}:`, selection)
    
    ctx.value.globalCompositeOperation = 'destination-out'
    ctx.value.fillStyle = 'rgba(0,0,0,1)'
    ctx.value.beginPath()
    ctx.value.arc(selection.x, selection.y, selection.radius, 0, Math.PI * 2)
    ctx.value.fill()
  })
  }
  
  // 恢复原始的绘图状态
  ctx.value.globalCompositeOperation = originalCompositeOperation
  
  saveHistory()
  clearSelection()
  ElMessage.success(`消除完成（处理了${brushStrokes.value.length}个画笔区域）`)
}

// 处理编辑器外部点击
const handleEditorClick = (event) => {
  // 工具栏现在在图片加载后始终显示，不在外部点击时隐藏
  // 但可以关闭一些临时的UI元素
  if (!canvasContainer.value.contains(event.target)) {
    showBrushPreview.value = false
    currentTool.value = null
  }
}

// 隐藏工具栏
const hideToolbar = () => {
  showToolbar.value = false
  showBrushPreview.value = false
  currentTool.value = null
  clearSelection()
}

// 撤销
const undo = () => {
  if (historyStep.value > 0) {
    historyStep.value--
    brushHistoryStep.value--
    restoreFromHistory()
  }
}

// 重做
const redo = () => {
  if (historyStep.value < history.value.length - 1) {
    historyStep.value++
    brushHistoryStep.value++
    restoreFromHistory()
  }
}

// 减小画笔尺寸
const decreaseBrushSize = () => {
  if (brushSize.value > minBrushSize) {
    brushSize.value -= 1
  }
}

// 增大画笔尺寸
const increaseBrushSize = () => {
  if (brushSize.value < maxBrushSize) {
    brushSize.value += 1
  }
}

// 获取堆叠图片的旋转角度
const getStackedImageRotation = (index) => {
  // 第一张: 0度
  // 第二张: 顺时针10度 (+10)
  // 第三张: 逆时针10度 (-10) 
  // 第四张: 顺时针20度 (+20)
  // 第五张: 逆时针20度 (-20)
  const rotations = [0, 5, -5, 10, -10]
  return rotations[index] || 0
}

// 处理滑块拇指鼠标按下事件
const handleThumbMouseDown = (event) => {
  event.preventDefault()
  isDragging.value = true
  document.addEventListener('mousemove', handleSliderMouseMove)
  document.addEventListener('mouseup', handleSliderMouseUp)
}

// 处理滑块轨道鼠标按下事件
const handleSliderMouseDown = (event) => {
  if (!sliderRef.value) return

  const rect = sliderRef.value.getBoundingClientRect()
  const offsetX = event.clientX - rect.left
  const percentage = Math.max(0, Math.min(1, offsetX / rect.width))

  brushSize.value = Math.round(minBrushSize + percentage * (maxBrushSize - minBrushSize))

  // 开始拖拽
  isDragging.value = true
  document.addEventListener('mousemove', handleSliderMouseMove)
  document.addEventListener('mouseup', handleSliderMouseUp)
}

// 处理滑块鼠标移动事件
const handleSliderMouseMove = (event) => {
  if (!isDragging.value || !sliderRef.value) return

  const rect = sliderRef.value.getBoundingClientRect()
  const offsetX = event.clientX - rect.left
  const percentage = Math.max(0, Math.min(1, offsetX / rect.width))

  brushSize.value = Math.round(minBrushSize + percentage * (maxBrushSize - minBrushSize))
}

// 处理滑块鼠标抬起事件
const handleSliderMouseUp = () => {
  isDragging.value = false
  document.removeEventListener('mousemove', handleSliderMouseMove)
  document.removeEventListener('mouseup', handleSliderMouseUp)
}

// 处理滑块键盘事件
const handleSliderKeyDown = (event) => {
  switch (event.key) {
    case 'ArrowLeft':
    case 'ArrowDown':
      event.preventDefault()
      decreaseBrushSize()
      break
    case 'ArrowRight':
    case 'ArrowUp':
      event.preventDefault()
      increaseBrushSize()
      break
    case 'Home':
      event.preventDefault()
      brushSize.value = minBrushSize
      break
    case 'End':
      event.preventDefault()
      brushSize.value = maxBrushSize
      break
  }
}

// 从历史记录恢复
const restoreFromHistory = () => {
  // 恢复主画布
  const mainImg = new Image()
  mainImg.onload = () => {
    ctx.value.clearRect(0, 0, canvas.value.width, canvas.value.height)
    ctx.value.drawImage(mainImg, 0, 0)
  }
  mainImg.src = history.value[historyStep.value]

  // 恢复画笔画布
  if (brushHistory.value[brushHistoryStep.value]) {
    const brushImg = new Image()
    brushImg.onload = () => {
      brushCtx.value.clearRect(0, 0, brushCanvasRef.value.width, brushCanvasRef.value.height)
      brushCtx.value.drawImage(brushImg, 0, 0)

      // 恢复后重新计算边界线
      updateBoundaryAfterRestore()
    }
    brushImg.src = brushHistory.value[brushHistoryStep.value]
  } else {
    // 如果没有对应的画笔历史，清空画笔画布
    brushCtx.value.clearRect(0, 0, brushCanvasRef.value.width, brushCanvasRef.value.height)

    // 清空后隐藏边界线
    hideBoundaryLine()
  }
}

// 导出图片
const exportImage = () => {
  return canvas.value.toDataURL('image/png')
}

// 构建多主体编辑的imageResKeyList参数
const buildImageResKeyList = async (type) => {
  const imageResKeyList = []
  // 将原图的filekey先存到imageResKeyList中
  // 从原始imageUrl获取原图
  const originalImageBlob = await fetch(props.imageUrl)
    .then(res => res.blob())
  const originalImageFile = new File([originalImageBlob], 'original.png', { type: originalImageBlob.type || 'image/png' })
  const originalUploadResult = await uploadFile(originalImageFile)
  const originalFileKey = originalUploadResult.data.fileKey
  imageResKeyList.push(originalFileKey)

  if (type === 'STORYBOARD') {
    if (imageFileKey.value) {
      imageResKeyList.push(imageFileKey.value)
    }
  }


  if (type === 'MULTI_BODY') {
    // 如果场景图存在设置场景图
    if (sceneImageUrl.value) {
      console.log('场景图存在设置场景图', sceneForm)
      if (sceneForm.sceneResKey) {
        imageResKeyList.push(sceneForm.sceneResKey)
      } else {
        imageResKeyList.push(sceneResKey.value)
      }
    }
    if (subjectFileKey.value) {
      imageResKeyList.push(subjectFileKey.value)
    }
    selectedActors.value.forEach(actor => {
      // 如果是上传的图片，直接使用resKey
      if (actor.perspective === 'UPLOADED' && actor.resKey) {
        imageResKeyList.push(actor.resKey)
        return
      }

      // 如果是选择的角色，查找对应的ResKey
      const selectedRole = getSelectedActor(actor.actorId)
      if (selectedRole && actor.perspective) {
        let resKey = ''
        switch (actor.perspective) {
          case 'WHOLE_BODY_FRONT':
            resKey = selectedRole.wholeBodyFrontImageResKey
            break
          case 'WHOLE_BODY_BACK':
            resKey = selectedRole.wholeBodyBackImageResKey
            break
          case 'WHOLE_BODY_SIDE':
            resKey = selectedRole.wholeBodySideImageResKey
            break
          case 'HALF_BODY':
            resKey = selectedRole.halfBodyImageResKey
            break
          default:
            resKey = selectedRole.resKey
        }

        if (resKey) {
          imageResKeyList.push(resKey)
        } else {
          console.warn(`角色 ${actor.actorName} 的 ${actor.perspective} 视图没有对应的ResKey`)
        }
      }
    })
  }

  return imageResKeyList
}

// 处理多主体编辑
const handleMultiSubjectEdit = async (type) => {

  // 检查是否有subjectPrompt值
  if (type === 'MULTI_BODY' && (!subjectPrompt.value || subjectPrompt.value.trim() === '')) {

  }
  if (type === 'STORYBOARD' && (!prompt.value || prompt.value.trim() === '')) {

  }

  try {
    // 启用扫光loading
    isScanning.value = true
    ElMessage.info('正在生成多主体图片...')

    // 构建imageResKeyList参数
    const imageResKeyList = await buildImageResKeyList(type)

    if (imageResKeyList.length === 0) {
      ElMessage.warning('未找到有效的角色图片，请检查角色数据')
      return
    }

    // 调用多主体编辑接口
    const params = {
      imageResKeyList: imageResKeyList,
      prompt: type === 'MULTI_BODY' ? subjectPrompt.value.trim() : prompt.value.trim(),
      businessType: props.businessType,
      businessId: props.businessId,
      modelProvider: modelProvider.value,
      resultNum: resultNum.value,
      dramaId: props.dramaId
    }

    console.log('多主体编辑参数:', params)

    const result = await multiSubjectEdit(params)

    ElMessage.success('多主体图片生成完成')
    console.log('Multi-subject edit result:', result)

    // 检查响应中是否有新的图片地址
    if (result.data) {
      const newImageUrl = result.data
      console.log('获取到多主体编辑后的图片地址:', newImageUrl)

      // 更新图片URL并重新加载
      await replaceImageAndReset(newImageUrl)

      ElMessage.success('图片已更新为多主体编辑结果')

      // 触发生成完成事件，通知父组件刷新记录
      emit('generation-completed', {
        type: 'multi-subject',
        imageUrl: newImageUrl
      })
    } else {
      console.warn('多主体编辑响应中未找到图片地址')
    }

  } catch (error) {
    console.error('多主体编辑失败:', error)
    ElMessage.error('多主体编辑失败: ' + (error.message || '未知错误'))
  } finally {
    // 关闭扫光loading
    isScanning.value = false
  }
}

// 更新多主体模式的提示词
const updateMultiBodyPrompt = () => {
  let promptParts = []
  let imageIndex = 1

  // 图一：原图
  promptParts.push(`图${imageIndex}为原图`)
  imageIndex++

  // 如果有参考图，图二为参考图
  if (hasReferenceImage.value) {
    promptParts.push(`图${imageIndex}为参考图`)
    imageIndex++
  }

  // 如果有场景图，接下来为场景图
  if (sceneImageUrl.value) {
    promptParts.push(`图${imageIndex}为场景图`)
    imageIndex++
  }

  // 遍历主体图
  selectedActors.value.forEach((actor, index) => {
    if (actor.perspective === 'UPLOADED') {
      // 上传的图片
      promptParts.push(`图${imageIndex}为角色图`)
    } else {
      // 选择的角色
      promptParts.push(`图${imageIndex}为角色-「${actor.actorName}」图`)
    }
    imageIndex++
  })

  // 生成最终提示词
  subjectPrompt.value = promptParts.join('，') + '。'
}

const handlePromptEdit = async () => {
}

// 生成掩码图片并上传
const generateMask = async () => {
  if (currentMode.value !== 'remove') {
    if (editType.value === 'MULTI_BODY' && subjectPrompt.value.trim() === '') {
      ElMessage.warning('请输入提示词')
    return
  }
    if (editType.value === 'STORYBOARD' && prompt.value.trim() === '') {
    ElMessage.warning('请输入提示词')
    return
    }
  }
  // 如果是多主体模式，或者没有掩码图/掩码图没有绘画区域，使用多主体编辑逻辑
  if (editType.value === 'MULTI_BODY') {
    return await handleMultiSubjectEdit('MULTI_BODY')
  }
  if ((!hasSelection.value && !checkIfHasSelection())) {
    return await handleMultiSubjectEdit('STORYBOARD')
  }

  try {
    // 启用扫光loading
    isScanning.value = true
    ElMessage.info('正在处理图片...')

    // 使用原始图片的自然尺寸（不考虑缩放）
    const originalWidth = imageDimensions.naturalWidth
    const originalHeight = imageDimensions.naturalHeight

    // 创建与原始图片尺寸相同的掩码画布
    const maskCanvas = document.createElement('canvas')
    const maskCtx = maskCanvas.getContext('2d')

    // 设置掩码画布尺寸为原始图片尺寸
    maskCanvas.width = originalWidth
    maskCanvas.height = originalHeight

    // 填充黑色背景
    maskCtx.fillStyle = '#000000'
    maskCtx.fillRect(0, 0, maskCanvas.width, maskCanvas.height)

    // 获取画笔画布的完整图像数据
    const brushImageData = brushCtx.value.getImageData(0, 0, brushCanvasRef.value.width, brushCanvasRef.value.height)
    const brushData = brushImageData.data

    // 创建掩码图像数据
    const maskImageData = maskCtx.createImageData(maskCanvas.width, maskCanvas.height)
    const maskData = maskImageData.data

    // 获取图片在画布中的显示信息
    const { drawX, drawY, drawWidth, drawHeight } = calculateImageDimensions()
    const scaledWidth = drawWidth * imageScale.value
    const scaledHeight = drawHeight * imageScale.value
    const scaledX = drawX + (drawWidth - scaledWidth) / 2 + imageOffset.x
    const scaledY = drawY + (drawHeight - scaledHeight) / 2 + imageOffset.y

    // 计算画布坐标到原始图片坐标的映射关系
    const canvasToOriginalScaleX = originalWidth / scaledWidth
    const canvasToOriginalScaleY = originalHeight / scaledHeight

    // 遍历掩码画布的每个像素
    for (let y = 0; y < maskCanvas.height; y++) {
      for (let x = 0; x < maskCanvas.width; x++) {
        // 将原始图片坐标转换为画布中的显示坐标
        const displayX = (x / canvasToOriginalScaleX) + scaledX
        const displayY = (y / canvasToOriginalScaleY) + scaledY

        // 确保在画布范围内
        if (displayX >= 0 && displayX < canvas.value.width && displayY >= 0 && displayY < canvas.value.height) {
          // 计算在画笔画布中的对应坐标
          const brushX = Math.round(displayX)
          const brushY = Math.round(displayY)

          // 获取画笔画布中对应像素的alpha值
          const brushIndex = (brushY * brushCanvasRef.value.width + brushX) * 4
          const alpha = brushData[brushIndex + 3]

          // 计算掩码画布中的像素索引
          const maskIndex = (y * maskCanvas.width + x) * 4

          if (alpha > 0) {
            // 有内容的地方设为白色
            maskData[maskIndex] = 255     // R
            maskData[maskIndex + 1] = 255 // G
            maskData[maskIndex + 2] = 255 // B
            maskData[maskIndex + 3] = 255 // A
          } else {
            // 没有内容的地方保持黑色
            maskData[maskIndex] = 0       // R
            maskData[maskIndex + 1] = 0   // G
            maskData[maskIndex + 2] = 0   // B
            maskData[maskIndex + 3] = 255 // A
          }
        }
      }
    }

    // 将处理后的图像数据放到掩码画布上
    maskCtx.putImageData(maskImageData, 0, 0)

    // 保存掩码图数据供自动选区使用
    savedMaskImageData.value = {
      imageData: maskImageData,
      width: maskCanvas.width,
      height: maskCanvas.height,
      originalWidth,
      originalHeight,
      scaledWidth,
      scaledHeight,
      scaledX,
      scaledY
    }

    // 从原始imageUrl获取原图
    const originalImageBlob = await fetch(props.imageUrl)
      .then(res => res.blob())
    const originalImageFile = new File([originalImageBlob], 'original.png', { type: originalImageBlob.type || 'image/png' })
    
    console.log(`擦除原图 - 来源: ${props.imageUrl}`)
    console.log(`擦除原图 - 文件大小: ${(originalImageFile.size / 1024 / 1024).toFixed(2)}MB, 类型: ${originalImageFile.type}`)

    // 将掩码图转换为File对象
    const maskImageBlob = await new Promise(resolve => {
      maskCanvas.toBlob(resolve, 'image/png')
    })
    const maskImageFile = new File([maskImageBlob], 'mask.png', { type: 'image/png' })
    
    console.log(`掩码图 - 尺寸: ${originalWidth}x${originalHeight}`)
    console.log(`掩码图 - 文件大小: ${(maskImageFile.size / 1024 / 1024).toFixed(2)}MB`)

    // 上传原图
    ElMessage.info('正在上传原图...')
    const originalUploadResult = await uploadFile(originalImageFile)
    const originalFileKey = originalUploadResult.data.fileKey
    console.log(`擦除原图上传成功 - fileKey: ${originalFileKey}`)

    // 上传掩码图
    ElMessage.info('正在上传掩码图...')
    const maskUploadResult = await uploadFile(maskImageFile)
    const maskFileKey = maskUploadResult.data.fileKey
    console.log(`掩码图上传成功 - fileKey: ${maskFileKey}`)

    // 调用图片重绘接口
    ElMessage.info('正在生成重绘图片...')
    const editParams = {
      businessType: props.businessType,
      businessImageResKey: originalFileKey,
      maskImageResKey: maskFileKey,
      businessId: props.businessId,
      prompt: prompt.value.trim()
    }

    const editResult = currentMode.value === 'redraw' ? await imageMaskEdit(editParams) : await imageRemoveEdit(editParams)
    
    ElMessage.success('图片重绘完成')
    console.log('Image mask edit result:', editResult)
    
    // 检查响应中是否有新的图片地址
    if (editResult.data) {
      const newImageUrl = editResult.data
      console.log('获取到重绘后的图片地址:', newImageUrl)
      
      // 更新图片URL并重新加载
      await replaceImageAndReset(newImageUrl)
      
      // 触发生成完成事件，通知父组件刷新记录
      emit('generation-completed', { 
        type: currentMode.value === 'redraw' ? 'redraw' : 'remove', 
        imageUrl: newImageUrl 
      })
    } else {
      console.warn('重绘响应中未找到图片地址')
      // 仍然清除选区
      clearSelection()
    }
    
  } catch (error) {
    console.error('生成掩码图片时出错:', error)
    ElMessage.error('生成掩码图片失败: ' + (error.message || '未知错误'))
  } finally {
    // 关闭扫光loading
    isScanning.value = false
  }
}

// 选择场景按钮点击
const selectScene = async () => {
  try {
    // 检查是否有剧本ID
    if (!props.dramaId) {
      ElMessage.warning('缺少剧本信息，无法获取场景列表')
      return
    }

    ElMessage.info('正在加载场景列表...')

    // 调用接口获取场景列表
    const { data: sceneData } = await getDramaScene(props.dramaId)
    scenes.value = sceneData || []

    // 重置场景表单
    sceneForm.sceneId = ''
    sceneForm.sceneName = ''
    sceneForm.sceneResKey = ''
    sceneForm.previewUrl = ''

    // 打开场景选择弹窗
    sceneDialogVisible.value = true

    ElMessage.success(`加载到 ${scenes.value.length} 个场景`)
  } catch (error) {
    console.error('获取场景列表失败:', error)
    ElMessage.error('获取场景列表失败: ' + (error.message || '未知错误'))
  }
}

// 选择主体按钮点击
const selectBody = () => {
  // 检查是否有角色数据
  if (!props.roles || props.roles.length === 0) {
    ElMessage.warning('当前没有可选择的角色，请先在角色管理中添加角色')
    return
  }

  // 每次打开都重置表单，不保留之前的选择
  actorForms.value = [createActorFormItem()]

  actorDialogVisible.value = true
}

// 创建角色表单项
const createActorFormItem = () => ({
  actorId: '',
  perspective: '',
  actorName: '',
  imageUrl: ''
})

// 添加新的角色表单项
const addActorForm = () => {
  console.log(actorForms.value.length , selectedActors.value.length)
  if (actorForms.value.length + selectedActors.value.length >= 5) {
    ElMessage.warning('最多只能选择5个角色')
    return
  }
  actorForms.value.push(createActorFormItem())
}

// 删除角色表单项
const removeActorForm = (index) => {
  if (actorForms.value.length <= 1) {
    ElMessage.warning('至少需要保留一个角色')
    return
  }
  actorForms.value.splice(index, 1)
}

// 处理角色选择变化
const handleActorSelectChange = (index, actorId) => {
  const formItem = actorForms.value[index]
  if (!formItem) return

  // 重置视图选择
  formItem.perspective = ''

  // 更新角色名称
  const selectedRole = getSelectedActor(actorId)
  if (selectedRole) {
    formItem.actorName = selectedRole.actorName
    formItem.actorId = actorId
  }
}

// 处理角色视图变化
const handlePerspectiveChange = (index, perspective) => {
  const formItem = actorForms.value[index]
  if (!formItem) return

  formItem.perspective = perspective

  // 更新图片URL
  const selectedRole = getSelectedActor(formItem.actorId)
  if (selectedRole) {
    switch (perspective) {
      case 'WHOLE_BODY_FRONT':
        formItem.imageUrl = selectedRole.wholeBodyFrontImageUrl
        break
      case 'WHOLE_BODY_SIDE':
        formItem.imageUrl = selectedRole.wholeBodySideImageUrl
        break
      case 'WHOLE_BODY_BACK':
        formItem.imageUrl = selectedRole.wholeBodyBackImageUrl
        break
      case 'HALF_BODY':
        formItem.imageUrl = selectedRole.halfBodyImageUrl
        break
      default:
        formItem.imageUrl = ''
    }
  }
}

// 获取指定的角色信息
const getSelectedActor = (actorId) => {
  if (!actorId || !props.roles || !props.roles.length) return null
  return props.roles.find(role => role.actorId === actorId)
}

// 确认角色选择
const handleConfirmSelectActor = () => {
  // 验证所有表单项
  const invalidForms = actorForms.value.filter(form => !form.actorId || !form.perspective)
  if (invalidForms.length > 0) {
    ElMessage.warning('请为所有角色选择角色和视图')
    return
  }

  // 构建新选择的角色数据
  const newActorData = actorForms.value.map(form => ({
    actorId: form.actorId,
    actorName: form.actorName,
    imageUrl: form.imageUrl,
    perspective: form.perspective
  }))

  // 添加到现有的selectedActors中，而不是替换
  selectedActors.value.push(...newActorData)

  // 为新添加的角色初始化删除图标显示状态
  const newDeleteIconStates = new Array(newActorData.length).fill(false)
  showDeleteIcon.value.push(...newDeleteIconStates)

  // 关闭弹窗
  actorDialogVisible.value = false

  ElMessage.success(`已添加 ${newActorData.length} 个角色`)

  // 更新多主体模式提示词
  if (editType.value === 'MULTI_BODY') {
    updateMultiBodyPrompt()
  }
}

// 删除选中的角色
const removeSelectedActor = (index) => {
  selectedActors.value.splice(index, 1)
  showDeleteIcon.value.splice(index, 1)

  // 更新多主体模式提示词
  if (editType.value === 'MULTI_BODY') {
    updateMultiBodyPrompt()
  }
}

// 处理参考图编辑
const handleReferenceImageEdit = (editData) => {
  console.log('编辑参考图:', editData)
  
  // 这里可以打开图片编辑弹窗
  // 由于ImageEditor本身就是一个图片编辑器，我们可以直接使用当前图片进行编辑
  // 或者触发父组件打开独立的图片编辑弹窗
  
  // 示例：触发父组件事件，让父组件处理图片编辑
  emit('reference-image-edit', editData)
}

// 删除参考图
const removeReferenceImage = () => {
  if (editType.value === 'STORYBOARD') {
    imageFileKey.value = ''
    // 清除PicUpload组件中的图片显示
    if (storyboardReferenceUpload.value) {
      storyboardReferenceUpload.value.clearImage()
    }
    ElMessage.success('参考图已删除')
  } else if (editType.value === 'MULTI_BODY') {
    subjectFileKey.value = ''
    hasReferenceImage.value = false
    // 清除PicUpload组件中的图片显示
    if (multiBodyReferenceUpload.value) {
      multiBodyReferenceUpload.value.clearImage()
    }
    updateMultiBodyPrompt()
    ElMessage.success('参考图已删除，提示词已更新')
  }
}

// 删除场景图
const removeSceneImage = () => {
  sceneImageUrl.value = ''
  sceneResKey.value = ''
  
  // 更新多主体模式提示词
  if (editType.value === 'MULTI_BODY') {
    updateMultiBodyPrompt()
  }
  
  ElMessage.success('场景图已删除')
}

// 场景选择变化处理
const handleSceneChange = (sceneId) => {
  // 根据选择的sceneId查找对应的场景信息
  const selectedScene = scenes.value.find(scene => scene.sceneId === sceneId)

  if (selectedScene) {
    // 设置场景信息
    sceneForm.sceneName = selectedScene.sceneName
    sceneForm.sceneResKey = selectedScene.sceneResKey
    // 设置场景预览图
    sceneForm.previewUrl = selectedScene.sceneImageUrl || ''
  }
}

// 场景图上传处理
const handleSceneImageUpload = () => {
  // 创建文件输入元素
  const input = document.createElement('input')
  input.type = 'file'
  input.accept = 'image/jpeg,image/jpg,image/png,image/webp'
  input.onchange = async (event) => {
    const file = event.target.files[0]
    if (!file) return

    // 验证文件类型和大小（复用PicUpload的验证逻辑）
    const supportedTypes = ['image/jpeg', 'image/jpg', 'image/png', 'image/webp']
    const maxSizeMB = 5

    if (!supportedTypes.includes(file.type)) {
      ElMessage.error('只能上传图片文件!')
      return
    }

    if (file.size / 1024 / 1024 > maxSizeMB) {
      ElMessage.error(`图片大小不能超过 ${maxSizeMB}MB!`)
      return
    }

    try {
      sceneUploadLoading.value = true

      // 显示上传中的预览
      const reader = new FileReader()
      reader.readAsDataURL(file)
      reader.onload = () => {
        sceneImageUrl.value = reader.result
      }

      // 复用PicUpload的上传流程
      const { data } = await getPutUrl(file.type)
      await putUrlToOss(data.url, file)

      if (data && data.fileKey) {
        sceneResKey.value = data.fileKey
        console.log('场景图上传成功，fileKey:', data.fileKey)
        ElMessage.success('场景图上传成功')

        // 更新多主体模式提示词
        if (editType.value === 'MULTI_BODY') {
          updateMultiBodyPrompt()
        }
      } else {
        throw new Error('上传失败')
      }
    } catch (error) {
      console.error('场景图上传失败:', error)
      ElMessage.error('场景图上传失败，请重试')
      // 清除预览图片
      sceneImageUrl.value = ''
    } finally {
      sceneUploadLoading.value = false
    }
  }
  input.click()
}

// 主体图上传处理
const handleSubjectImageUpload = () => {
  // 创建文件输入元素
  const input = document.createElement('input')
  input.type = 'file'
  input.accept = 'image/jpeg,image/jpg,image/png,image/webp'
  input.onchange = async (event) => {
    const file = event.target.files[0]
    if (!file) return

    // 验证文件类型和大小
    const supportedTypes = ['image/jpeg', 'image/jpg', 'image/png', 'image/webp']
    const maxSizeMB = 5

    if (!supportedTypes.includes(file.type)) {
      ElMessage.error('只能上传图片文件!')
      return
    }

    if (file.size / 1024 / 1024 > maxSizeMB) {
      ElMessage.error(`图片大小不能超过 ${maxSizeMB}MB!`)
      return
    }

    try {
      subjectUploadLoading.value = true

      // 复用PicUpload的上传流程
      const { data } = await getPutUrl(file.type)
      await putUrlToOss(data.url, file)

      if (data && data.fileKey) {
        // 显示上传后的预览
        const reader = new FileReader()
        reader.readAsDataURL(file)
        reader.onload = () => {
          // 构建对象并添加到selectedActors
          const uploadedActor = {
            imageUrl: reader.result,
            resKey: data.fileKey,
            actorId: 'uploaded_' + Date.now(), // 生成唯一ID
            actorName: '上传图片',
            perspective: 'UPLOADED' // 标记为上传的图片
          }

          // 添加到selectedActors数组
          selectedActors.value.push(uploadedActor)

          // 更新删除图标显示状态
          showDeleteIcon.value.push(false)

          console.log('主体图上传成功，fileKey:', data.fileKey)
          ElMessage.success('主体图上传成功')

          // 更新多主体模式提示词
          if (editType.value === 'MULTI_BODY') {
            updateMultiBodyPrompt()
          }
        }
      } else {
        throw new Error('上传失败')
      }
    } catch (error) {
      console.error('主体图上传失败:', error)
      ElMessage.error('主体图上传失败，请重试')
    } finally {
      subjectUploadLoading.value = false
    }
  }
  input.click()
}

// 确认场景选择
const handleConfirmSelectScene = async () => {
  if (!sceneFormRef.value) return

  try {
    await sceneFormRef.value.validate()

    // 根据选择的sceneId查找对应的场景信息
    const selectedScene = scenes.value.find(scene => scene.sceneId === sceneForm.sceneId)

    // 更新当前选中的场景图片URL用于反显
    sceneImageUrl.value = selectedScene?.sceneImageUrl || sceneForm.previewUrl

    // 关闭弹窗
    sceneDialogVisible.value = false

    ElMessage.success(`已选择场景: ${sceneForm.sceneName}`)
    console.log('选中的场景信息:', {
      sceneId: sceneForm.sceneId,
      sceneName: sceneForm.sceneName,
      sceneResKey: sceneForm.sceneResKey,
      sceneImageUrl: sceneImageUrl.value
    })

    // 更新多主体模式提示词
    if (editType.value === 'MULTI_BODY') {
      updateMultiBodyPrompt()
    }
  } catch (error) {
    console.error('表单验证失败:', error)
    ElMessage.error('表单验证失败，请检查输入')
  }
}

// 替换图片并重置编辑器
const replaceImageAndReset = async (newImageUrl) => {
  try {
    console.log('开始替换图片并重置编辑器:', newImageUrl)
    
    // 重置所有状态
    toolbarLevel.value = 1
    currentMode.value = null
    currentTool.value = null
    showBrushPreview.value = false
    
    // 清除所有选区和绘制状态
    clearSelection()
    
    // 清除画笔轨迹
    brushStrokes.value = []
    currentStroke.value = null
    
    // 清除智能选区相关状态
    smartSelectionMasks.value = []
    isSmartSelectionMode.value = false
    
    // 重置图片缩放和偏移
    imageScale.value = 1
    imageOffset.x = 0
    imageOffset.y = 0
    
    // 显示控制点
    showControlPoints.value = true
    
    // 清除所有画布
    if (ctx.value) {
      ctx.value.clearRect(0, 0, canvas.value.width, canvas.value.height)
    }
    if (brushCtx.value) {
      brushCtx.value.clearRect(0, 0, brushCanvasRef.value.width, brushCanvasRef.value.height)
    }
    if (autoSelectCtx.value) {
      autoSelectCtx.value.clearRect(0, 0, autoSelectCanvasRef.value.width, autoSelectCanvasRef.value.height)
    }
    if (selectionCtx.value) {
      selectionCtx.value.clearRect(0, 0, selectionCanvasRef.value.width, selectionCanvasRef.value.height)
    }
    if (antsCtx.value) {
      antsCtx.value.clearRect(0, 0, antsCanvasRef.value.width, antsCanvasRef.value.height)
    }
    if (controlCtx.value) {
      controlCtx.value.clearRect(0, 0, controlCanvasRef.value.width, controlCanvasRef.value.height)
    }
    
    // 隐藏边界线
    hideBoundaryLine()
    
    // 创建新的图片对象并加载
    const newImage = new Image()
    newImage.crossOrigin = 'anonymous'
    
    await new Promise((resolve, reject) => {
      newImage.onload = () => {
        // 更新图片引用
        image.value = newImage
        
        // 记录新图片尺寸信息
        imageDimensions.naturalWidth = newImage.width
        imageDimensions.naturalHeight = newImage.height
        imageDimensions.width = newImage.width
        imageDimensions.height = newImage.height
        
        console.log('新图片加载完成:', newImage.width, newImage.height)
        
        // 绘制新图片
        drawImage()
        
        // 保存新的原始图片状态
        originalImageData.value = canvas.value.toDataURL()
        
        // 重置历史记录
        history.value = [originalImageData.value]
        historyStep.value = 0
        
        // 重置画笔历史记录
        brushHistory.value = [brushCanvasRef.value.toDataURL()]
        brushHistoryStep.value = 0
        
        // 更新控制点
        updateControlPoints()
        
        // 触发图片加载完成事件
        emit('image-loaded')
        emit('image-dimensions-detected', {
          naturalWidth: imageDimensions.naturalWidth,
          naturalHeight: imageDimensions.naturalHeight,
          displayWidth: imageDimensions.width,
          displayHeight: imageDimensions.height
        })
        
        resolve()
      }
      
      newImage.onerror = (error) => {
        console.error('新图片加载失败:', error)
        reject(error)
      }
      
      newImage.src = newImageUrl
    })
    
    console.log('图片替换和重置完成')
    
  } catch (error) {
    console.error('替换图片时出错:', error)
    ElMessage.error('替换图片失败: ' + (error.message || '未知错误'))
  }
}

// 重置编辑器
const resetEditor = () => {
  // 清除所有状态，但保持工具栏显示
  toolbarLevel.value = 1
  currentMode.value = null
  currentTool.value = null
  showBrushPreview.value = false
  clearSelection()

  // 重置图片缩放和偏移
  imageScale.value = 1
  imageOffset.x = 0
  imageOffset.y = 0

  // 显示控制点
  showControlPoints.value = true

  // 清除画笔轨迹
  brushStrokes.value = []
  currentStroke.value = null
  
  // 清除智能选区相关状态
  smartSelectionMasks.value = []
  isSmartSelectionMode.value = false
  
  // 使用保存的原始图片数据恢复
  if (originalImageData.value) {
    const img = new Image()
    img.onload = () => {
      // 清空画布并重新绘制原始图片
      ctx.value.clearRect(0, 0, canvas.value.width, canvas.value.height)
      ctx.value.drawImage(img, 0, 0)
      
      // 重置历史记录
      history.value = [originalImageData.value]
      historyStep.value = 0

      // 重置画笔历史记录
      brushHistory.value = [brushCanvasRef.value.toDataURL()]
      brushHistoryStep.value = 0
      
      ElMessage.success('已恢复到原始图片')
    }
    img.src = originalImageData.value
  } else if (imageLoaded.value) {
    // 备用方案：重新绘制当前图片
    drawImage()
    originalImageData.value = canvas.value.toDataURL()

    // 重置画笔历史记录
    brushHistory.value = [brushCanvasRef.value.toDataURL()]
    brushHistoryStep.value = 0

    saveHistory()
    ElMessage.success('已恢复到原始图片')
  }
}

// 窗口大小变化处理
const handleResize = () => {
  // 重新设置画布尺寸
  if (canvas.value) {
    setCanvasSize(canvasWidth.value, canvasHeight.value)
    // 如果图片已加载，需要重新绘制
    if (imageLoaded.value) {
      drawImage()
    }
  }
}

// 组件挂载时初始化
onMounted(() => {
  initCanvas()
  // 监听窗口大小变化
  window.addEventListener('resize', handleResize)

  // 如果已经有imageUrl，延迟加载图片
  if (props.imageUrl) {
    nextTick(() => {
      loadImage()
    })
  }
})

// 组件卸载时清理
onUnmounted(() => {
  hideBoundaryLine()
  // 移除窗口大小监听器
  window.removeEventListener('resize', handleResize)
})

// 获取图片尺寸信息
const getImageDimensions = () => {
  return { ...imageDimensions }
}

// 暴露方法给父组件
defineExpose({
  exportImage,
  undo,
  redo,
  clearSelection,
  hideToolbar,
  resetEditor,
  generateMask,
  getImageDimensions,
  replaceImageAndReset
})
</script>

<style scoped>
:deep(.el-select--small .el-select__wrapper) {
  border-radius: 6px;
}
.select-wrapper {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 8px;
  width: 86px;
  height: 120px;
  border: 1px dashed #d9d9d9;
}

.select-label {
  font-size: 12px;
  color: var(--text-color-2);
}

.select-btn {
  width: 56px;
  height: 24px;
  border: 1px solid rgba(31, 35, 41, 0.08);
  border-radius: 4px;
  color: var(--text-color-primary);
  font-size: 12px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.3s ease;
}

.select-btn:hover {
  background-color: rgba(28, 29, 41, 0.05);
  border-color: rgba(28, 29, 41, 0.15);
}

.select-btn:disabled {
  cursor: not-allowed;
  opacity: 0.6;
  background-color: rgba(31, 35, 41, 0.05);
}

/* 参考图容器样式 */
.reference-image-container {
  position: relative;
  display: inline-block;
}

/* 场景图片相关样式 */
.scene-image-container {
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: 6px;
}

.scene-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  border-radius: 6px;
}

.scene-image-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 8px;
  opacity: 0;
  animation: fadeIn 0.2s ease-in-out forwards;
}

.scene-image-overlay .select-btn {
  background: rgba(255, 255, 255, 0.9);
  border: 1px solid rgba(255, 255, 255, 0.2);
  backdrop-filter: blur(8px);
  color: var(--text-color-primary);
}

.scene-image-overlay .select-btn:hover {
  background: rgba(255, 255, 255, 1);
  border-color: var(--primary-color);
  color: var(--primary-color);
}

.scene-upload-loading {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(255, 255, 255, 0.8);
  display: flex;
  justify-content: center;
  align-items: center;
  border-radius: 6px;
}

.loading-spinner {
  width: 20px;
  height: 20px;
  border: 2px solid #f3f3f3;
  border-top: 2px solid #1c1d29;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes fadeIn {
  from {
    opacity: 0;
  }

  to {
    opacity: 1;
  }
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }

  100% {
    transform: rotate(360deg);
  }
}

/* 模式选择 */
.mode-wrapper {
  height: 180px;
  background-color: var(--bg-color-2);
  border-radius: 8px;
  width: 820px;
  margin: 0 auto 16px auto;
  display: flex;
  flex-direction: column;
}

.mode-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-right: 12px;
}

.mode-header-title {
  font-size: 16px;
  width: 80px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-color-primary);
  font-size: 14px;
  cursor: pointer;
}

.mode-header-title.selected {
  font-weight: 500;
  color: var(--text-color-primary);
}

.mode-content {
  background: #fff;
  flex: 1;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 0 12px;
  position: relative;
}

.send-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 8px;
  background: var(--text-color-primary);
  position: absolute;
  right: 24px;
  bottom: 24px;
  cursor: pointer;
}

.send-btn.disabled {
  background: #BCBFCC;
  cursor: not-allowed;
}

.image-editor {
  position: fixed;
  top: 0;
  left: 100px;
  user-select: none;
  max-width: 100vw;
  max-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
}

.canvas-container {
  position: relative;
}

.main-canvas,
.brush-canvas,
.selection-canvas,
.ants-canvas {
  position: absolute;
  top: 0;
  left: 0;
  cursor: crosshair;
}

.brush-canvas {
  pointer-events: none;
  z-index: 2;
  /* 确保画笔画布可见 */
}

.selection-canvas {
  pointer-events: none;
  z-index: 3;
}

.ants-canvas {
  pointer-events: none;
  z-index: 4;
}

.control-canvas {
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: none;
  z-index: 5;
}

.auto-select-canvas {
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: none;
  z-index: 6;
}

/* 扫光loading效果 */
.scanning-overlay {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  z-index: 10;
  border-radius: 8px;
  overflow: hidden;
}

.scanning-background {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.6);
  backdrop-filter: blur(4px);
}

.scanning-light {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: linear-gradient(205.92deg, rgba(192, 206, 255, 0.5) 1.74%, rgba(205, 242, 255, 0.5) 52.4%, rgba(248, 206, 255, 0.5) 105.69%);
  background-size: 200% 200%;
  animation: gradientMove 4s ease infinite;
  z-index: 2;
}

.tool-line {
  width: 1px;
  height: 18px;
  background: rgba(28, 29, 41, 0.08);
}

@keyframes gradientMove {
  0% {
    background-position: 0% 100%;
  }

  50% {
    background-position: 100% 0%;
  }

  100% {
    background-position: 0% 100%;
  }
}

.scanning-text {
  position: relative;
  color: white;
  margin-top: 20px;
  font-size: 14px;
  font-weight: 500;
  text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
  z-index: 2;
}


/* 固定工具栏 */
.floating-toolbar {
  background: white;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  padding: 12px;
  border: 1px solid #e0e0e0;
}

.toolbar-level-1 {
  display: flex;
  box-shadow: 0px 0px 16px 0px #7F839426;
  padding: 2px;
  border-radius: 12px;
  align-items: center;
  z-index: 2000;
  background: #fff;
}

.toolbar-level-2 {
  display: flex;
  align-items: center;
  gap: 8px;
  z-index: 2000;
  background: #fff;
}

.current-mode {
  padding: 4px 8px;
  background: #f0f0f0;
  border-radius: 4px;
  font-size: 12px;
  white-space: nowrap;
}

.tool-group {
  display: flex;
  align-items: center;
  gap: 4px;
}

.tool-btn {
  padding: 0 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 36px;
  border-radius: 12px;
  font-size: 14px;
  color: var(--text-color-primary);
  cursor: pointer;
}

.tool-btn-sub {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 34px;
  width: 34px;
  border-radius: 6px;
  font-size: 14px;
  color: var(--text-color-primary);
  cursor: pointer;
}
.tool-btn-text {
  color: #64687A;
  font-size: 14px;
  width: 128px;
  text-align: center;
}

.tool-btn-sub.selected {
  background: rgba(162, 166, 184, 0.1);
}



.tool-btn:hover {
  background: rgba(162, 166, 184, 0.1);
}

.tool-btn.close-btn {
  color: #999;
}

.tool-btn.reset-btn {
  background: #e6a23c;
  color: white;
  border-color: #e6a23c;
}



.tool-btn.erase-btn {
  background: #f56c6c;
  color: white;
  border-color: #f56c6c;
}

.tool-btn:disabled {
  background: #f5f5f5;
  color: #c0c4cc;
  border-color: #e4e7ed;
  cursor: not-allowed;
}

/* Tooltip容器 */
.tooltip-wrapper {
  position: relative;
}

/* Hover提示样式 */
.hover-tooltip {
  position: absolute;
  top: -35px;
  left: 50%;
  transform: translateX(-50%);
  background: rgba(0, 0, 0, 0.8);
  color: white;
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 12px;
  white-space: nowrap;
  z-index: 1000;
  opacity: 0;
  visibility: hidden;
  transition: all 0.2s ease;
  pointer-events: none;
}

/* Tooltip箭头 */
.hover-tooltip::before {
  content: '';
  position: absolute;
  bottom: -4px;
  left: 50%;
  transform: translateX(-50%);
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 4px solid rgba(0, 0, 0, 0.8);
}

/* Hover时显示tooltip */
.tooltip-wrapper:hover .hover-tooltip {
  opacity: 1;
  visibility: visible;
}

.tool-separator {
  width: 1px;
  height: 24px;
  background: #ddd;
  margin: 0 4px;
}

.size-adjuster {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* 自定义滑块样式 */
.custom-slider {
  width: 60px;
  height: 20px;
  display: flex;
  align-items: center;
  cursor: pointer;
  padding: 7px 0;
  /* 增加点击区域 */
  border-radius: 3px;
  outline: none;
}

.custom-slider:focus {
  outline: none;
  border: none;
}

.slider-track {
  position: relative;
  width: 100%;
  height: 6px;
  background: #EBEDF2;
  border-radius: 3px;
  overflow: visible;
}

.slider-fill {
  position: absolute;
  left: 0;
  top: 0;
  height: 100%;
  background: #3644E0;
  border-radius: 3px;
  transition: width 0.1s ease;
  max-width: 100%;
}

.slider-thumb {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 10px;
  height: 10px;
  background: #3644E0;
  border-radius: 50%;
  cursor: grab;
  transition: left 0.1s ease;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
}

.slider-thumb:hover {
  transform: translateY(-50%) scale(1.1);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
}

.slider-thumb:active,
.slider-thumb.dragging {
  cursor: grabbing;
  transform: translateY(-50%) scale(1.1);
}

.size-display {
  font-size: 12px;
  min-width: 20px;
  text-align: center;
}

/* 提示词输入 */
.prompt-input-container {
  position: absolute;
  z-index: 20;
  min-width: 300px;
}

.prompt-input-wrapper {
  display: flex;
  gap: 8px;
  background: white;
  padding: 8px;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.prompt-input {
  flex: 1;
  padding: 8px 12px;
  border: 1px solid #ddd;
  border-radius: 4px;
  font-size: 14px;
}

.execute-btn {
  padding: 8px 16px;
  background: #409eff;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
}

.execute-btn:disabled {
  background: #ccc;
  cursor: not-allowed;
}

/* 消除按钮 */
.remove-execute-container {
  position: absolute;
  z-index: 20;
}

.remove-execute-btn {
  padding: 12px 24px;
  background: #f56c6c;
  color: white;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  font-size: 16px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.remove-execute-btn:disabled {
  background: #ccc;
  cursor: not-allowed;
}

/* 画笔预览 */
.brush-preview {
  position: absolute;
  background-color: rgba(100, 112, 250, 0.5);
  border: 2px solid rgba(100, 112, 250, 0.8);
  border-radius: 50%;
  pointer-events: none;
  z-index: 15;
  box-sizing: border-box;
}

/* 固定工具栏样式 */
.fixed-toolbar {
  position: absolute;
  display: flex;
  justify-content: center;
  z-index: 10;
  pointer-events: auto;
}

/* 图标样式 (使用iconfont或自定义图标) */
.icon-redraw::before {
  content: "🎨";
}

.icon-remove::before {
  content: "🗑️";
}

.icon-auto-select::before {
  content: "🎯";
}

.icon-brush::before {
  content: "🖌️";
}

.icon-eraser::before {
  content: "🧹";
}

.icon-undo::before {
  content: "↶";
}

.icon-redo::before {
  content: "↷";
}

.icon-reset::before {
  content: "🔄";
}

.icon-mask::before {
  content: "🎭";
}

.icon-close::before {
  content: "✖️";
}

/* 堆叠图片样式 */
.stacked-images-container {
  position: relative;
  margin-right: 16px;
  width: 70px;
  /* 固定宽度，不随展开状态改变 */
  height: 120px;
  /* 固定高度 */
  overflow: visible;
  flex-shrink: 0;
  /* 防止被压缩 */
}

.stacked-images {
  position: relative;
  width: 70px;
  height: 120px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.stacked-image {
  position: absolute;
  width: 70px;
  height: 120px;
  transform-origin: center center;
  transition: all 0.3s ease;
  cursor: pointer;
}

.stacked-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 6px;
  border: 2px solid #fff;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}

.expanded-images {
  display: flex;
  gap: 8px;
  align-items: flex-start;
  position: absolute;
  top: 0;
  left: 0;
  z-index: 1000;
}

.expanded-image {
  position: relative;
  width: 70px;
  height: 120px;
  cursor: pointer;
  transition: transform 0.2s ease;
}

.expanded-image:hover {
  transform: scale(1.05);
}

.expanded-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 6px;
  border: 2px solid #fff;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}

.delete-icon {
  position: absolute;
  top: -8px;
  left: -8px;
  width: 20px;
  height: 20px;
  background-color: #fff;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: white;
  font-size: 12px;
  z-index: 10;
  transition: all 0.2s ease;
  box-shadow: 0px 0px 8px 0px #7F839426;
  border: 1px solid A2A6B852;
}

.delete-icon:hover {
  background-color: #fff;
  transform: scale(1.1);
}

/* 角色选择弹窗样式 */
.actor-select-header-close {
  display: flex;
  justify-content: space-between;
  margin-bottom: 22px;
  font-size: 16px;
  color: var(--text-color-primary);
  font-weight: 500;
}

.actor-select-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  width: 100%;
}

.header-title {
  font-size: 14px;
  color: var(--text-color-2);
}

.actor-select-content {
  margin-top: -24px;
  max-height: 500px;
  overflow-y: auto;
}

.actor-form-item {
  margin-bottom: 20px;
}

.actor-form-item:last-child {
  margin-bottom: 0;
}

.form-item {
  margin-bottom: 15px;
}

.form-label {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  font-weight: 500;
  color: #303133;
  margin-bottom: 8px;
}

.required-mark {
  color: #f56c6c;
  margin-left: 4px;
}

.delete-button {
  padding: 0 !important;
  min-height: auto !important;
  height: auto !important;
  border: none !important;
  background: transparent !important;
}

.delete-button:hover {
  background: rgba(245, 108, 108, 0.1) !important;
}

.actor-images-preview {
  margin-top: 20px;
}

.actor-images-grid {
  display: flex;
  gap: 16px;
}

.actor-image-item {
  position: relative;
  border: 2px solid transparent;
  border-radius: 4px;
  overflow: hidden;
  cursor: pointer;
  transition: all 0.3s;
}

.actor-view-image {
  width: 100px;
  height: 100px;
  border-radius: 8px;
  object-fit: cover;
}

.actor-view-placeholder {
  width: 100px;
  height: 100px;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #f5f7fa;
  color: #909399;
  font-size: 14px;
  border-radius: 8px;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
}

/* 场景预览图片样式 (复用分镜详情中的样式) */
.scene-preview-image {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

/* 场景缩略图样式 */
.scene-thumbnail {
  width: 80px;
  height: 60px;
  object-fit: cover;
  border-radius: 6px;
  border: 1px solid #ddd;
  margin-bottom: 8px;
}

.select-scene-btn {
  cursor: pointer;
  color: #409eff;
  transition: color 0.2s ease;
}

.select-scene-btn:hover {
  color: #66b1ff;
}
</style>